/**
 * @fileoverview Comma style - enforces comma styles of two types: last and first
 * @author Vignesh Anand aka vegetableman
 */

"use strict";

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

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = {
    meta: {
        type: "layout",

        docs: {
            description: "enforce consistent comma style",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/comma-style"
        },

        fixable: "code",

        schema: [
            {
                enum: ["first", "last"]
            },
            {
                type: "object",
                properties: {
                    exceptions: {
                        type: "object",
                        additionalProperties: {
                            type: "boolean"
                        }
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.",
            expectedCommaFirst: "',' should be placed first.",
            expectedCommaLast: "',' should be placed last."
        }
    },

    create(context) {
        const style = context.options[0] || "last",
            sourceCode = context.getSourceCode();
        const exceptions = {
            ArrayPattern: true,
            ArrowFunctionExpression: true,
            CallExpression: true,
            FunctionDeclaration: true,
            FunctionExpression: true,
            ImportDeclaration: true,
            ObjectPattern: true,
            NewExpression: true
        };

        if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) {
            const keys = Object.keys(context.options[1].exceptions);

            for (let i = 0; i < keys.length; i++) {
                exceptions[keys[i]] = context.options[1].exceptions[keys[i]];
            }
        }

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

        /**
         * Modified text based on the style
         * @param {string} styleType Style type
         * @param {string} text Source code text
         * @returns {string} modified text
         * @private
         */
        function getReplacedText(styleType, text) {
            switch (styleType) {
                case "between":
                    return `,${text.replace(astUtils.LINEBREAK_MATCHER, "")}`;

                case "first":
                    return `${text},`;

                case "last":
                    return `,${text}`;

                default:
                    return "";
            }
        }

        /**
         * Determines the fixer function for a given style.
         * @param {string} styleType comma style
         * @param {ASTNode} previousItemToken The token to check.
         * @param {ASTNode} commaToken The token to check.
         * @param {ASTNode} currentItemToken The token to check.
         * @returns {Function} Fixer function
         * @private
         */
        function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) {
            const text =
                sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) +
                sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]);
            const range = [previousItemToken.range[1], currentItemToken.range[0]];

            return function(fixer) {
                return fixer.replaceTextRange(range, getReplacedText(styleType, text));
            };
        }

        /**
         * Validates the spacing around single items in lists.
         * @param {Token} previousItemToken The last token from the previous item.
         * @param {Token} commaToken The token representing the comma.
         * @param {Token} currentItemToken The first token of the current item.
         * @param {Token} reportItem The item to use when reporting an error.
         * @returns {void}
         * @private
         */
        function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) {

            // if single line
            if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
                    astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {

                // do nothing.

            } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
                    !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {

                const comment = sourceCode.getCommentsAfter(commaToken)[0];
                const styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment)
                    ? style
                    : "between";

                // lone comma
                context.report({
                    node: reportItem,
                    loc: {
                        line: commaToken.loc.end.line,
                        column: commaToken.loc.start.column
                    },
                    messageId: "unexpectedLineBeforeAndAfterComma",
                    fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken)
                });

            } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {

                context.report({
                    node: reportItem,
                    messageId: "expectedCommaFirst",
                    fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
                });

            } else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {

                context.report({
                    node: reportItem,
                    loc: {
                        line: commaToken.loc.end.line,
                        column: commaToken.loc.end.column
                    },
                    messageId: "expectedCommaLast",
                    fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
                });
            }
        }

        /**
         * Checks the comma placement with regards to a declaration/property/element
         * @param {ASTNode} node The binary expression node to check
         * @param {string} property The property of the node containing child nodes.
         * @private
         * @returns {void}
         */
        function validateComma(node, property) {
            const items = node[property],
                arrayLiteral = (node.type === "ArrayExpression" || node.type === "ArrayPattern");

            if (items.length > 1 || arrayLiteral) {

                // seed as opening [
                let previousItemToken = sourceCode.getFirstToken(node);

                items.forEach(item => {
                    const commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken,
                        currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken),
                        reportItem = item || currentItemToken;

                    /*
                     * This works by comparing three token locations:
                     * - previousItemToken is the last token of the previous item
                     * - commaToken is the location of the comma before the current item
                     * - currentItemToken is the first token of the current item
                     *
                     * These values get switched around if item is undefined.
                     * previousItemToken will refer to the last token not belonging
                     * to the current item, which could be a comma or an opening
                     * square bracket. currentItemToken could be a comma.
                     *
                     * All comparisons are done based on these tokens directly, so
                     * they are always valid regardless of an undefined item.
                     */
                    if (astUtils.isCommaToken(commaToken)) {
                        validateCommaItemSpacing(previousItemToken, commaToken,
                            currentItemToken, reportItem);
                    }

                    if (item) {
                        const tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken);

                        previousItemToken = tokenAfterItem
                            ? sourceCode.getTokenBefore(tokenAfterItem)
                            : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1];
                    }
                });

                /*
                 * Special case for array literals that have empty last items, such
                 * as [ 1, 2, ]. These arrays only have two items show up in the
                 * AST, so we need to look at the token to verify that there's no
                 * dangling comma.
                 */
                if (arrayLiteral) {

                    const lastToken = sourceCode.getLastToken(node),
                        nextToLastToken = sourceCode.getTokenBefore(lastToken);

                    if (astUtils.isCommaToken(nextToLastToken)) {
                        validateCommaItemSpacing(
                            sourceCode.getTokenBefore(nextToLastToken),
                            nextToLastToken,
                            lastToken,
                            lastToken
                        );
                    }
                }
            }
        }

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

        const nodes = {};

        if (!exceptions.VariableDeclaration) {
            nodes.VariableDeclaration = function(node) {
                validateComma(node, "declarations");
            };
        }
        if (!exceptions.ObjectExpression) {
            nodes.ObjectExpression = function(node) {
                validateComma(node, "properties");
            };
        }
        if (!exceptions.ObjectPattern) {
            nodes.ObjectPattern = function(node) {
                validateComma(node, "properties");
            };
        }
        if (!exceptions.ArrayExpression) {
            nodes.ArrayExpression = function(node) {
                validateComma(node, "elements");
            };
        }
        if (!exceptions.ArrayPattern) {
            nodes.ArrayPattern = function(node) {
                validateComma(node, "elements");
            };
        }
        if (!exceptions.FunctionDeclaration) {
            nodes.FunctionDeclaration = function(node) {
                validateComma(node, "params");
            };
        }
        if (!exceptions.FunctionExpression) {
            nodes.FunctionExpression = function(node) {
                validateComma(node, "params");
            };
        }
        if (!exceptions.ArrowFunctionExpression) {
            nodes.ArrowFunctionExpression = function(node) {
                validateComma(node, "params");
            };
        }
        if (!exceptions.CallExpression) {
            nodes.CallExpression = function(node) {
                validateComma(node, "arguments");
            };
        }
        if (!exceptions.ImportDeclaration) {
            nodes.ImportDeclaration = function(node) {
                validateComma(node, "specifiers");
            };
        }
        if (!exceptions.NewExpression) {
            nodes.NewExpression = function(node) {
                validateComma(node, "arguments");
            };
        }

        return nodes;
    }
};
