/**
 * @fileoverview Rule to enforce concise object methods and properties.
 * @author Jamund Ferguson
 */

"use strict";

const OPTIONS = {
    always: "always",
    never: "never",
    methods: "methods",
    properties: "properties",
    consistent: "consistent",
    consistentAsNeeded: "consistent-as-needed"
};

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "require or disallow method and property shorthand syntax for object literals",
            category: "ECMAScript 6",
            recommended: false,
            url: "https://eslint.org/docs/rules/object-shorthand"
        },

        fixable: "code",

        schema: {
            anyOf: [
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always", "methods", "properties", "never", "consistent", "consistent-as-needed"]
                        }
                    ],
                    minItems: 0,
                    maxItems: 1
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always", "methods", "properties"]
                        },
                        {
                            type: "object",
                            properties: {
                                avoidQuotes: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always", "methods"]
                        },
                        {
                            type: "object",
                            properties: {
                                ignoreConstructors: {
                                    type: "boolean"
                                },
                                avoidQuotes: {
                                    type: "boolean"
                                },
                                avoidExplicitReturnArrows: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                }
            ]
        }
    },

    create(context) {
        const APPLY = context.options[0] || OPTIONS.always;
        const APPLY_TO_METHODS = APPLY === OPTIONS.methods || APPLY === OPTIONS.always;
        const APPLY_TO_PROPS = APPLY === OPTIONS.properties || APPLY === OPTIONS.always;
        const APPLY_NEVER = APPLY === OPTIONS.never;
        const APPLY_CONSISTENT = APPLY === OPTIONS.consistent;
        const APPLY_CONSISTENT_AS_NEEDED = APPLY === OPTIONS.consistentAsNeeded;

        const PARAMS = context.options[1] || {};
        const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors;
        const AVOID_QUOTES = PARAMS.avoidQuotes;
        const AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows;
        const sourceCode = context.getSourceCode();

        //--------------------------------------------------------------------------
        // Helpers
        //--------------------------------------------------------------------------

        const CTOR_PREFIX_REGEX = /[^_$0-9]/u;

        /**
         * Determines if the first character of the name is a capital letter.
         * @param {string} name The name of the node to evaluate.
         * @returns {boolean} True if the first character of the property name is a capital letter, false if not.
         * @private
         */
        function isConstructor(name) {
            const match = CTOR_PREFIX_REGEX.exec(name);

            // Not a constructor if name has no characters apart from '_', '$' and digits e.g. '_', '$$', '_8'
            if (!match) {
                return false;
            }

            const firstChar = name.charAt(match.index);

            return firstChar === firstChar.toUpperCase();
        }

        /**
         * Determines if the property can have a shorthand form.
         * @param {ASTNode} property Property AST node
         * @returns {boolean} True if the property can have a shorthand form
         * @private
         *
         */
        function canHaveShorthand(property) {
            return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadElement" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty");
        }

        /**
         * Checks whether a node is a string literal.
         * @param   {ASTNode} node - Any AST node.
         * @returns {boolean} `true` if it is a string literal.
         */
        function isStringLiteral(node) {
            return node.type === "Literal" && typeof node.value === "string";
        }

        /**
         * Determines if the property is a shorthand or not.
         * @param {ASTNode} property Property AST node
         * @returns {boolean} True if the property is considered shorthand, false if not.
         * @private
         *
         */
        function isShorthand(property) {

            // property.method is true when `{a(){}}`.
            return (property.shorthand || property.method);
        }

        /**
         * Determines if the property's key and method or value are named equally.
         * @param {ASTNode} property Property AST node
         * @returns {boolean} True if the key and value are named equally, false if not.
         * @private
         *
         */
        function isRedundant(property) {
            const value = property.value;

            if (value.type === "FunctionExpression") {
                return !value.id; // Only anonymous should be shorthand method.
            }
            if (value.type === "Identifier") {
                return astUtils.getStaticPropertyName(property) === value.name;
            }

            return false;
        }

        /**
         * Ensures that an object's properties are consistently shorthand, or not shorthand at all.
         * @param   {ASTNode} node Property AST node
         * @param   {boolean} checkRedundancy Whether to check longform redundancy
         * @returns {void}
         *
         */
        function checkConsistency(node, checkRedundancy) {

            // We are excluding getters/setters and spread properties as they are considered neither longform nor shorthand.
            const properties = node.properties.filter(canHaveShorthand);

            // Do we still have properties left after filtering the getters and setters?
            if (properties.length > 0) {
                const shorthandProperties = properties.filter(isShorthand);

                /*
                 * If we do not have an equal number of longform properties as
                 * shorthand properties, we are using the annotations inconsistently
                 */
                if (shorthandProperties.length !== properties.length) {

                    // We have at least 1 shorthand property
                    if (shorthandProperties.length > 0) {
                        context.report({ node, message: "Unexpected mix of shorthand and non-shorthand properties." });
                    } else if (checkRedundancy) {

                        /*
                         * If all properties of the object contain a method or value with a name matching it's key,
                         * all the keys are redundant.
                         */
                        const canAlwaysUseShorthand = properties.every(isRedundant);

                        if (canAlwaysUseShorthand) {
                            context.report({ node, message: "Expected shorthand for all properties." });
                        }
                    }
                }
            }
        }

        /**
         * Fixes a FunctionExpression node by making it into a shorthand property.
         * @param {SourceCodeFixer} fixer The fixer object
         * @param {ASTNode} node A `Property` node that has a `FunctionExpression` or `ArrowFunctionExpression` as its value
         * @returns {Object} A fix for this node
         */
        function makeFunctionShorthand(fixer, node) {
            const firstKeyToken = node.computed
                ? sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken)
                : sourceCode.getFirstToken(node.key);
            const lastKeyToken = node.computed
                ? sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken)
                : sourceCode.getLastToken(node.key);
            const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]);
            let keyPrefix = "";

            if (sourceCode.commentsExistBetween(lastKeyToken, node.value)) {
                return null;
            }

            if (node.value.async) {
                keyPrefix += "async ";
            }
            if (node.value.generator) {
                keyPrefix += "*";
            }

            if (node.value.type === "FunctionExpression") {
                const functionToken = sourceCode.getTokens(node.value).find(token => token.type === "Keyword" && token.value === "function");
                const tokenBeforeParams = node.value.generator ? sourceCode.getTokenAfter(functionToken) : functionToken;

                return fixer.replaceTextRange(
                    [firstKeyToken.range[0], node.range[1]],
                    keyPrefix + keyText + sourceCode.text.slice(tokenBeforeParams.range[1], node.value.range[1])
                );
            }
            const arrowToken = sourceCode.getTokenBefore(node.value.body, { filter: token => token.value === "=>" });
            const tokenBeforeArrow = sourceCode.getTokenBefore(arrowToken);
            const hasParensAroundParameters = tokenBeforeArrow.type === "Punctuator" && tokenBeforeArrow.value === ")";
            const oldParamText = sourceCode.text.slice(sourceCode.getFirstToken(node.value, node.value.async ? 1 : 0).range[0], tokenBeforeArrow.range[1]);
            const newParamText = hasParensAroundParameters ? oldParamText : `(${oldParamText})`;

            return fixer.replaceTextRange(
                [firstKeyToken.range[0], node.range[1]],
                keyPrefix + keyText + newParamText + sourceCode.text.slice(arrowToken.range[1], node.value.range[1])
            );

        }

        /**
         * Fixes a FunctionExpression node by making it into a longform property.
         * @param {SourceCodeFixer} fixer The fixer object
         * @param {ASTNode} node A `Property` node that has a `FunctionExpression` as its value
         * @returns {Object} A fix for this node
         */
        function makeFunctionLongform(fixer, node) {
            const firstKeyToken = node.computed ? sourceCode.getTokens(node).find(token => token.value === "[") : sourceCode.getFirstToken(node.key);
            const lastKeyToken = node.computed ? sourceCode.getTokensBetween(node.key, node.value).find(token => token.value === "]") : sourceCode.getLastToken(node.key);
            const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]);
            let functionHeader = "function";

            if (node.value.async) {
                functionHeader = `async ${functionHeader}`;
            }
            if (node.value.generator) {
                functionHeader = `${functionHeader}*`;
            }

            return fixer.replaceTextRange([node.range[0], lastKeyToken.range[1]], `${keyText}: ${functionHeader}`);
        }

        /*
         * To determine whether a given arrow function has a lexical identifier (`this`, `arguments`, `super`, or `new.target`),
         * create a stack of functions that define these identifiers (i.e. all functions except arrow functions) as the AST is
         * traversed. Whenever a new function is encountered, create a new entry on the stack (corresponding to a different lexical
         * scope of `this`), and whenever a function is exited, pop that entry off the stack. When an arrow function is entered,
         * keep a reference to it on the current stack entry, and remove that reference when the arrow function is exited.
         * When a lexical identifier is encountered, mark all the arrow functions on the current stack entry by adding them
         * to an `arrowsWithLexicalIdentifiers` set. Any arrow function in that set will not be reported by this rule,
         * because converting it into a method would change the value of one of the lexical identifiers.
         */
        const lexicalScopeStack = [];
        const arrowsWithLexicalIdentifiers = new WeakSet();
        const argumentsIdentifiers = new WeakSet();

        /**
         * Enters a function. This creates a new lexical identifier scope, so a new Set of arrow functions is pushed onto the stack.
         * Also, this marks all `arguments` identifiers so that they can be detected later.
         * @returns {void}
         */
        function enterFunction() {
            lexicalScopeStack.unshift(new Set());
            context.getScope().variables.filter(variable => variable.name === "arguments").forEach(variable => {
                variable.references.map(ref => ref.identifier).forEach(identifier => argumentsIdentifiers.add(identifier));
            });
        }

        /**
         * Exits a function. This pops the current set of arrow functions off the lexical scope stack.
         * @returns {void}
         */
        function exitFunction() {
            lexicalScopeStack.shift();
        }

        /**
         * Marks the current function as having a lexical keyword. This implies that all arrow functions
         * in the current lexical scope contain a reference to this lexical keyword.
         * @returns {void}
         */
        function reportLexicalIdentifier() {
            lexicalScopeStack[0].forEach(arrowFunction => arrowsWithLexicalIdentifiers.add(arrowFunction));
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        return {
            Program: enterFunction,
            FunctionDeclaration: enterFunction,
            FunctionExpression: enterFunction,
            "Program:exit": exitFunction,
            "FunctionDeclaration:exit": exitFunction,
            "FunctionExpression:exit": exitFunction,

            ArrowFunctionExpression(node) {
                lexicalScopeStack[0].add(node);
            },
            "ArrowFunctionExpression:exit"(node) {
                lexicalScopeStack[0].delete(node);
            },

            ThisExpression: reportLexicalIdentifier,
            Super: reportLexicalIdentifier,
            MetaProperty(node) {
                if (node.meta.name === "new" && node.property.name === "target") {
                    reportLexicalIdentifier();
                }
            },
            Identifier(node) {
                if (argumentsIdentifiers.has(node)) {
                    reportLexicalIdentifier();
                }
            },

            ObjectExpression(node) {
                if (APPLY_CONSISTENT) {
                    checkConsistency(node, false);
                } else if (APPLY_CONSISTENT_AS_NEEDED) {
                    checkConsistency(node, true);
                }
            },

            "Property:exit"(node) {
                const isConciseProperty = node.method || node.shorthand;

                // Ignore destructuring assignment
                if (node.parent.type === "ObjectPattern") {
                    return;
                }

                // getters and setters are ignored
                if (node.kind === "get" || node.kind === "set") {
                    return;
                }

                // only computed methods can fail the following checks
                if (node.computed && node.value.type !== "FunctionExpression" && node.value.type !== "ArrowFunctionExpression") {
                    return;
                }

                //--------------------------------------------------------------
                // Checks for property/method shorthand.
                if (isConciseProperty) {
                    if (node.method && (APPLY_NEVER || AVOID_QUOTES && isStringLiteral(node.key))) {
                        const message = APPLY_NEVER ? "Expected longform method syntax." : "Expected longform method syntax for string literal keys.";

                        // { x() {} } should be written as { x: function() {} }
                        context.report({
                            node,
                            message,
                            fix: fixer => makeFunctionLongform(fixer, node)
                        });
                    } else if (APPLY_NEVER) {

                        // { x } should be written as { x: x }
                        context.report({
                            node,
                            message: "Expected longform property syntax.",
                            fix: fixer => fixer.insertTextAfter(node.key, `: ${node.key.name}`)
                        });
                    }
                } else if (APPLY_TO_METHODS && !node.value.id && (node.value.type === "FunctionExpression" || node.value.type === "ArrowFunctionExpression")) {
                    if (IGNORE_CONSTRUCTORS && node.key.type === "Identifier" && isConstructor(node.key.name)) {
                        return;
                    }
                    if (AVOID_QUOTES && isStringLiteral(node.key)) {
                        return;
                    }

                    // {[x]: function(){}} should be written as {[x]() {}}
                    if (node.value.type === "FunctionExpression" ||
                        node.value.type === "ArrowFunctionExpression" &&
                        node.value.body.type === "BlockStatement" &&
                        AVOID_EXPLICIT_RETURN_ARROWS &&
                        !arrowsWithLexicalIdentifiers.has(node.value)
                    ) {
                        context.report({
                            node,
                            message: "Expected method shorthand.",
                            fix: fixer => makeFunctionShorthand(fixer, node)
                        });
                    }
                } else if (node.value.type === "Identifier" && node.key.name === node.value.name && APPLY_TO_PROPS) {

                    // {x: x} should be written as {x}
                    context.report({
                        node,
                        message: "Expected property shorthand.",
                        fix(fixer) {
                            return fixer.replaceText(node, node.value.name);
                        }
                    });
                } else if (node.value.type === "Identifier" && node.key.type === "Literal" && node.key.value === node.value.name && APPLY_TO_PROPS) {
                    if (AVOID_QUOTES) {
                        return;
                    }

                    // {"x": x} should be written as {x}
                    context.report({
                        node,
                        message: "Expected property shorthand.",
                        fix(fixer) {
                            return fixer.replaceText(node, node.value.name);
                        }
                    });
                }
            }
        };
    }
};
