class Random
{
    constructor(seed)
    {
        this.seed = seed % 2147483647;
        if (this.seed <= 0)
            this.seed += 2147483646;
    }

    get next()
    {
        return this.seed = this.seed * 16807 % 2147483647;
    }

    underOne()
    {
        return (this.next % 1048576) / 1048576;
    }

    chance(chance)
    {
        if (!chance)
            return false;
        return this.underOne() < chance;
    }

    number(under)
    {
        return this.next % under;
    }

    numberSquareWeightedToLow(under)
    {
        const random = this.underOne();
        const random2 = random * random;
        return Math.floor(random2 * under);
    }
}

function nextAnimationFrame()
{
    return new Promise(resolve => requestAnimationFrame(resolve));
}

class StyleBench
{
    static defaultConfiguration()
    {
        return {
            name: 'Default',
            elementTypeCount: 10,
            idChance: 0.05,
            elementChance: 0.5,
            classCount: 200,
            classChance: 0.3,
            starChance: 0.05,
            attributeChance: 0.02,
            attributeCount: 10,
            attributeValueCount: 20,
            attributeOperators: ['','='],
            elementClassChance: 0.5,
            elementMaximumClasses: 3,
            elementAttributeChance: 0.2,
            elementMaximumAttributes: 3,
            combinators: [' ', '>',],
            pseudoClasses: [],
            pseudoClassChance: 0,
            beforeAfterChance: 0,
            maximumSelectorLength: 6,
            ruleCount: 5000,
            elementCount: 20000,
            maximumTreeDepth: 6,
            maximumTreeWidth: 50,
            repeatingSequenceChance: 0.2,
            repeatingSequenceMaximumLength: 3,
            leafMutationChance: 0.1,
            mediaQueryChance: 0,
            mediaQueryCloseChance: 0,
            styleSeed: 1,
            domSeed: 2,
            stepCount: 5,
            isResizeTest: false,
            mutationsPerStep: 100,
        };
    }

    static descendantCombinatorConfiguration()
    {
        return Object.assign(this.defaultConfiguration(), {
            name: 'Descendant and child combinators',
        });
    }

    static siblingCombinatorConfiguration()
    {
        return Object.assign(this.defaultConfiguration(), {
            name: 'Sibling combinators',
            combinators: [' ', ' ', '>', '>', '~', '+',],
        });
    }

    static structuralPseudoClassConfiguration()
    {
        return Object.assign(this.defaultConfiguration(), {
            name: 'Structural pseudo classes',
            pseudoClassChance: 0.1,
            pseudoClasses: [
                'first-child',
                'last-child',
                'first-of-type',
                'last-of-type',
                'only-of-type',
                'empty',
            ],
        });
    }

    static nthPseudoClassConfiguration()
    {
        return Object.assign(this.defaultConfiguration(), {
            name: 'Nth pseudo classes',
            pseudoClassChance: 0.1,
            pseudoClasses: [
                'nth-child(2n+1)',
                'nth-last-child(3n)',
                'nth-of-type(3n)',
                'nth-last-of-type(4n)',
            ],
        });
    }

    static beforeAndAfterConfiguration()
    {
        return Object.assign(this.defaultConfiguration(), {
            name: 'Before and after pseudo elements',
            beforeAfterChance: 0.1,
        });
    }

    static mediaQueryConfiguration()
    {
        return Object.assign(this.defaultConfiguration(), {
            name: 'Dynamic media queries',
            isResizeTest : true,
            mediaQueryChance: 0.01,
            mediaQueryCloseChance: 0.3,
            starChance: 0,
            elementCount: 5000,
        });
    }

    static predefinedConfigurations()
    {
        return [
            this.descendantCombinatorConfiguration(),
            this.siblingCombinatorConfiguration(),
            this.structuralPseudoClassConfiguration(),
            this.nthPseudoClassConfiguration(),
            this.beforeAndAfterConfiguration(),
            this.mediaQueryConfiguration(),
        ];
    }

    constructor(configuration)
    {
        this.configuration = configuration;
        this.idCount = 0;

        this.baseStyle = document.createElement("style");
        this.baseStyle.textContent = `
            #testroot {
                font-size: 10px;
                line-height: 10px;
            }
            #testroot * {
                display: inline-block;
                height:10px;
                min-width:10px;
            }
        `;
        document.head.appendChild(this.baseStyle);

        this.random = new Random(this.configuration.styleSeed);
        this.makeStyle();

        this.random = new Random(this.configuration.domSeed);
        this.makeTree();
    }

    randomElementName()
    {
        const elementTypeCount = this.configuration.elementTypeCount;
        return `elem${ this.random.numberSquareWeightedToLow(elementTypeCount) }`;
    }

    randomClassName()
    {
        const classCount = this.configuration.classCount;
        return `class${ this.random.numberSquareWeightedToLow(classCount) }`;
    }

    randomClassNameFromRange(range)
    {
        const maximum = Math.round(range * this.configuration.classCount);
        return `class${ this.random.numberSquareWeightedToLow(maximum) }`;
    }

    randomAttributeName()
    {
        const attributeCount = this.configuration.attributeCount;
        return `attr${ this.random.numberSquareWeightedToLow(attributeCount) }`;
    }

    randomAttributeValue()
    {
        const attributeValueCount = this.configuration.attributeValueCount;
        const valueNum = this.random.numberSquareWeightedToLow(attributeValueCount);
        if (valueNum == 0)
            return "";
        if (valueNum == 1)
            return "val";
        return `val${valueNum}`;
    }

    randomCombinator()
    {
        const combinators = this.configuration.combinators;
        return combinators[this.random.number(combinators.length)]
    }

    randomPseudoClass(isLast)
    {
        const pseudoClasses = this.configuration.pseudoClasses;
        const pseudoClass = pseudoClasses[this.random.number(pseudoClasses.length)]
        if (!isLast && pseudoClass == 'empty')
            return this.randomPseudoClass(isLast);
        return pseudoClass;
    }

    randomId()
    {
        const idCount = this.configuration.idChance * this.configuration.elementCount ;
        return `id${ this.random.number(idCount) }`;
    }

    randomAttributeSelector()
    {
        const name = this.randomAttributeName();
        const operators = this.configuration.attributeOperators;
        const operator = operators[this.random.numberSquareWeightedToLow(operators.length)];
        if (operator == '')
            return `[${name}]`;
        const value = this.randomAttributeValue();
        return `[${name}${operator}"${value}"]`;
    }

    makeCompoundSelector(index, length)
    {
        const isFirst = index == 0;
        const isLast = index == length - 1;
        const usePseudoClass = this.random.chance(this.configuration.pseudoClassChance) && this.configuration.pseudoClasses.length;
        const useId = isFirst && this.random.chance(this.configuration.idChance);
        const useElement = !useId && (usePseudoClass || this.random.chance(this.configuration.elementChance)); // :nth-of-type etc only make sense with element
        const useAttribute = !useId && this.random.chance(this.configuration.attributeChance);
        const useIdElementOrAttribute = useId || useElement || useAttribute;
        const useStar = !useIdElementOrAttribute && !isFirst && this.random.chance(this.configuration.starChance);
        const useClass = !useId && !useStar && (!useIdElementOrAttribute || this.random.chance(this.configuration.classChance));
        const useBeforeOrAfter = isLast && this.random.chance(this.configuration.beforeAfterChance);
        let result = "";
        if (useElement)
            result += this.randomElementName();
        if (useStar)
            result = "*";
        if (useId)
            result += "#" + this.randomId();
        if (useClass) {
            const classCount = this.random.numberSquareWeightedToLow(2) + 1;
            for (let i = 0; i < classCount; ++i) {
                // Use a smaller pool of class names on the left side of the selectors to create containers.
                result += "." + this.randomClassNameFromRange((index + 1) / length);
            }
        }
        if (useAttribute)
            result += this.randomAttributeSelector();

        if (usePseudoClass)
            result +=  ":" + this.randomPseudoClass(isLast);
        if (useBeforeOrAfter) {
            if (this.random.chance(0.5))
                result +=  "::before";
            else
                result +=  "::after";
        }
        return result;
    }

    makeSelector()
    {
        const length = this.random.number(this.configuration.maximumSelectorLength) + 1;
        let result = this.makeCompoundSelector(0, length);
        for (let i = 1; i < length; ++i) {
            const combinator = this.randomCombinator();
            if (combinator != ' ')
                result += " " + combinator;
            result += " " + this.makeCompoundSelector(i, length);
        }
        return result;
    }

    get randomColorComponent()
    {
        return this.random.next % 256;
    }

    makeDeclaration(selector)
    {
        let declaration = `background-color: rgb(${this.randomColorComponent}, ${this.randomColorComponent}, ${this.randomColorComponent});`;

        if (selector.endsWith('::before') || selector.endsWith('::after'))
            declaration += " content: ''; min-width:5px; display:inline-block;";

        return declaration;
    }

    makeRule()
    {
        const selector = this.makeSelector();
        return selector + " { " + this.makeDeclaration(selector) + " }";
    }

    makeMediaQuery()
    {
        let width = this.random.number(500);
        width = 300 + width - (width % 100);
        if (this.random.chance(0.5))
            return `@media (min-width: ${width}px) {`;
        return `@media (max-width: ${width}px) {`;
    }

    makeStylesheet(size)
    {
        let cssText = "";

        let inMediaQuery = false;
        for (let i = 0; i < size; ++i) {
            if (!inMediaQuery && this.random.chance(this.configuration.mediaQueryChance)) {
                cssText += this.makeMediaQuery() + "\n";;
                inMediaQuery = true;
            }

            cssText += this.makeRule() + "\n";

            if (inMediaQuery && this.random.chance(this.configuration.mediaQueryCloseChance)) {
                 cssText += "}\n";
                 inMediaQuery = false;
             }
        }
        return cssText;
    }

    makeStyle()
    {
        this.testStyle = document.createElement("style");
        this.testStyle.textContent = this.makeStylesheet(this.configuration.ruleCount);

        document.head.appendChild(this.testStyle);
    }

    makeElement()
    {
        const element = document.createElement(this.randomElementName());
        const hasClasses = this.random.chance(this.configuration.elementClassChance);
        const hasAttributes = this.random.chance(this.configuration.elementAttributeChance);
        if (hasClasses) {
            const count = this.random.numberSquareWeightedToLow(this.configuration.elementMaximumClasses) + 1;
            for (let i = 0; i < count; ++i)
                element.classList.add(this.randomClassName());
        }
        if (hasAttributes) {
            const count = this.random.number(this.configuration.elementMaximumAttributes) + 1;
            for (let i = 0; i < count; ++i)
                element.setAttribute(this.randomAttributeName(), this.randomAttributeValue());
        }
        const hasId = this.random.chance(this.configuration.idChance);
        if (hasId) {
            element.id = `id${ this.idCount }`;
            this.idCount++;
        }
        return element;
    }

    makeTreeWithDepth(parent, remainingCount, depth)
    {
        const maximumDepth = this.configuration.maximumTreeDepth;
        const maximumWidth =  this.configuration.maximumTreeWidth;
        const nonEmptyChance = (maximumDepth - depth) / maximumDepth;

        const shouldRepeat = this.random.chance(this.configuration.repeatingSequenceChance);
        const repeatingSequenceLength = shouldRepeat ? this.random.number(this.configuration.repeatingSequenceMaximumLength) + 1 : 0;

        let childCount = 0;
        if (depth == 0)
            childCount = remainingCount;
        else if (this.random.chance(nonEmptyChance))
            childCount = this.random.number(maximumWidth * depth / maximumDepth);

        let repeatingSequence = [];
        let repeatingSequenceSize = 0;
        for (let i = 0; i < childCount; ++i) {
            if (shouldRepeat && repeatingSequence.length == repeatingSequenceLength && repeatingSequenceSize < remainingCount) {
                for (const subtree of repeatingSequence)
                    parent.appendChild(subtree.cloneNode(true));
                remainingCount -= repeatingSequenceSize;
                if (!remainingCount)
                    return 0;
                continue;
            }
            const element = this.makeElement();
            parent.appendChild(element);

            if (!--remainingCount)
                return 0;
            remainingCount = this.makeTreeWithDepth(element, remainingCount, depth + 1);
            if (!remainingCount)
                return 0;

            if (shouldRepeat && repeatingSequence.length < repeatingSequenceLength) {
                repeatingSequence.push(element);
                repeatingSequenceSize += element.querySelectorAll("*").length + 1;
            }
        }
        return remainingCount;
    }

    makeTree()
    {
        this.testRoot = document.querySelector("#testroot");
        const elementCount = this.configuration.elementCount;

        this.makeTreeWithDepth(this.testRoot, elementCount, 0);

        this.updateCachedTestElements();
    }

    updateCachedTestElements()
    {
        this.testElements = this.testRoot.querySelectorAll("*");
    }

    randomTreeElement()
    {
        const randomIndex = this.random.number(this.testElements.length);
        return this.testElements[randomIndex]
    }

    addClasses(count)
    {
        for (let i = 0; i < count;) {
            const element = this.randomTreeElement();
            // There are more leaves than branches. Avoid skewing towards leaf mutations.
            if (!element.firstChild && !this.random.chance(this.configuration.leafMutationChance))
                continue;
            ++i;
            const classList = element.classList;
            classList.add(this.randomClassName());
        }
    }

    removeClasses(count)
    {
        for (let i = 0; i < count;) {
            const element = this.randomTreeElement();
            const classList = element.classList;
            if (!element.firstChild && !this.random.chance(this.configuration.leafMutationChance))
                continue;
            if (!classList.length)
                continue;
            ++i;
            classList.remove(classList[0]);
        }
    }

    addLeafElements(count)
    {
        for (let i = 0; i < count;) {
            const parent = this.randomTreeElement();
            // Avoid altering tree shape by turning many leaves into containers.
            if (!parent.firstChild)
                continue;
            ++i;
            const children = parent.childNodes;
            const index = this.random.number(children.length + 1);
            parent.insertBefore(this.makeElement(), children[index]);
        }
        this.updateCachedTestElements();
    }

    removeLeafElements(count)
    {
        for (let i = 0; i < count;) {
            const element = this.randomTreeElement();

            const canRemove = !element.firstChild && element.parentNode;
            if (!canRemove)
                continue;
            ++i;
            element.parentNode.removeChild(element);
        }
        this.updateCachedTestElements();
    }

    mutateAttributes(count)
    {
        for (let i = 0; i < count;) {
            const element = this.randomTreeElement();
            // There are more leaves than branches. Avoid skewing towards leaf mutations.
            if (!element.firstChild && !this.random.chance(this.configuration.leafMutationChance))
                continue;
            const attributeNames = element.getAttributeNames();
            let mutatedAttributes = false;
            for (const name of attributeNames) {
                if (name == "class" || name == "id")
                    continue;
                if (this.random.chance(0.5))
                    element.removeAttribute(name);
                else
                    element.setAttribute(name, this.randomAttributeValue());
                mutatedAttributes = true;
            }
            if (!mutatedAttributes) {
                const attributeCount = this.random.number(this.configuration.elementMaximumAttributes) + 1;
                for (let j = 0; j < attributeCount; ++j)
                    element.setAttribute(this.randomAttributeName(), this.randomAttributeValue());
            }
            ++i;
        }
    }

    resizeViewToWidth(width)
    {
        window.frameElement.style.width = width + "px";
    }

    async runForever()
    {
        while (true) {
            this.addClasses(10);
            this.removeClasses(10);
            this.addLeafElements(10);
            this.removeLeafElements(10);
            this.mutateAttributes(10);

            await nextAnimationFrame();
        }
    }
}
