/**
 * @fileoverview Rule to flag missing semicolons.
 * @author Nicholas C. Zakas
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const FixTracker = require("../util/fix-tracker");
const astUtils = require("../ast-utils");

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

module.exports = {
    meta: {
        docs: {
            description: "require or disallow semicolons instead of ASI",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/semi"
        },

        fixable: "code",

        schema: {
            anyOf: [
                {
                    type: "array",
                    items: [
                        {
                            enum: ["never"]
                        },
                        {
                            type: "object",
                            properties: {
                                beforeStatementContinuationChars: {
                                    enum: ["always", "any", "never"]
                                }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always"]
                        },
                        {
                            type: "object",
                            properties: {
                                omitLastInOneLineBlock: { type: "boolean" }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                }
            ]
        }
    },

    create(context) {

        const OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-`
        const options = context.options[1];
        const never = context.options[0] === "never";
        const exceptOneLine = Boolean(options && options.omitLastInOneLineBlock);
        const beforeStatementContinuationChars = (options && options.beforeStatementContinuationChars) || "any";
        const sourceCode = context.getSourceCode();

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

        /**
         * Reports a semicolon error with appropriate location and message.
         * @param {ASTNode} node The node with an extra or missing semicolon.
         * @param {boolean} missing True if the semicolon is missing.
         * @returns {void}
         */
        function report(node, missing) {
            const lastToken = sourceCode.getLastToken(node);
            let message,
                fix,
                loc = lastToken.loc;

            if (!missing) {
                message = "Missing semicolon.";
                loc = loc.end;
                fix = function(fixer) {
                    return fixer.insertTextAfter(lastToken, ";");
                };
            } else {
                message = "Extra semicolon.";
                loc = loc.start;
                fix = function(fixer) {

                    /*
                     * Expand the replacement range to include the surrounding
                     * tokens to avoid conflicting with no-extra-semi.
                     * https://github.com/eslint/eslint/issues/7928
                     */
                    return new FixTracker(fixer, sourceCode)
                        .retainSurroundingTokens(lastToken)
                        .remove(lastToken);
                };
            }

            context.report({
                node,
                loc,
                message,
                fix
            });

        }

        /**
         * Check whether a given semicolon token is redandant.
         * @param {Token} semiToken A semicolon token to check.
         * @returns {boolean} `true` if the next token is `;` or `}`.
         */
        function isRedundantSemi(semiToken) {
            const nextToken = sourceCode.getTokenAfter(semiToken);

            return (
                !nextToken ||
                astUtils.isClosingBraceToken(nextToken) ||
                astUtils.isSemicolonToken(nextToken)
            );
        }

        /**
         * Check whether a given token is the closing brace of an arrow function.
         * @param {Token} lastToken A token to check.
         * @returns {boolean} `true` if the token is the closing brace of an arrow function.
         */
        function isEndOfArrowBlock(lastToken) {
            if (!astUtils.isClosingBraceToken(lastToken)) {
                return false;
            }
            const node = sourceCode.getNodeByRangeIndex(lastToken.range[0]);

            return (
                node.type === "BlockStatement" &&
                node.parent.type === "ArrowFunctionExpression"
            );
        }

        /**
         * Check whether a given node is on the same line with the next token.
         * @param {Node} node A statement node to check.
         * @returns {boolean} `true` if the node is on the same line with the next token.
         */
        function isOnSameLineWithNextToken(node) {
            const prevToken = sourceCode.getLastToken(node, 1);
            const nextToken = sourceCode.getTokenAfter(node);

            return !!nextToken && astUtils.isTokenOnSameLine(prevToken, nextToken);
        }

        /**
         * Check whether a given node can connect the next line if the next line is unreliable.
         * @param {Node} node A statement node to check.
         * @returns {boolean} `true` if the node can connect the next line.
         */
        function maybeAsiHazardAfter(node) {
            const t = node.type;

            if (t === "DoWhileStatement" ||
                t === "BreakStatement" ||
                t === "ContinueStatement" ||
                t === "DebuggerStatement" ||
                t === "ImportDeclaration" ||
                t === "ExportAllDeclaration"
            ) {
                return false;
            }
            if (t === "ReturnStatement") {
                return Boolean(node.argument);
            }
            if (t === "ExportNamedDeclaration") {
                return Boolean(node.declaration);
            }
            if (isEndOfArrowBlock(sourceCode.getLastToken(node, 1))) {
                return false;
            }

            return true;
        }

        /**
         * Check whether a given token can connect the previous statement.
         * @param {Token} token A token to check.
         * @returns {boolean} `true` if the token is one of `[`, `(`, `/`, `+`, `-`, ```, `++`, and `--`.
         */
        function maybeAsiHazardBefore(token) {
            return (
                Boolean(token) &&
                OPT_OUT_PATTERN.test(token.value) &&
                token.value !== "++" &&
                token.value !== "--"
            );
        }

        /**
         * Check if the semicolon of a given node is unnecessary, only true if:
         *   - next token is a valid statement divider (`;` or `}`).
         *   - next token is on a new line and the node is not connectable to the new line.
         * @param {Node} node A statement node to check.
         * @returns {boolean} whether the semicolon is unnecessary.
         */
        function canRemoveSemicolon(node) {
            if (isRedundantSemi(sourceCode.getLastToken(node))) {
                return true; // `;;` or `;}`
            }
            if (isOnSameLineWithNextToken(node)) {
                return false; // One liner.
            }
            if (beforeStatementContinuationChars === "never" && !maybeAsiHazardAfter(node)) {
                return true; // ASI works. This statement doesn't connect to the next.
            }
            if (!maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) {
                return true; // ASI works. The next token doesn't connect to this statement.
            }

            return false;
        }

        /**
         * Checks a node to see if it's in a one-liner block statement.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} whether the node is in a one-liner block statement.
         */
        function isOneLinerBlock(node) {
            const parent = node.parent;
            const nextToken = sourceCode.getTokenAfter(node);

            if (!nextToken || nextToken.value !== "}") {
                return false;
            }
            return (
                !!parent &&
                parent.type === "BlockStatement" &&
                parent.loc.start.line === parent.loc.end.line
            );
        }

        /**
         * Checks a node to see if it's followed by a semicolon.
         * @param {ASTNode} node The node to check.
         * @returns {void}
         */
        function checkForSemicolon(node) {
            const isSemi = astUtils.isSemicolonToken(sourceCode.getLastToken(node));

            if (never) {
                if (isSemi && canRemoveSemicolon(node)) {
                    report(node, true);
                } else if (!isSemi && beforeStatementContinuationChars === "always" && maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) {
                    report(node);
                }
            } else {
                const oneLinerBlock = (exceptOneLine && isOneLinerBlock(node));

                if (isSemi && oneLinerBlock) {
                    report(node, true);
                } else if (!isSemi && !oneLinerBlock) {
                    report(node);
                }
            }
        }

        /**
         * Checks to see if there's a semicolon after a variable declaration.
         * @param {ASTNode} node The node to check.
         * @returns {void}
         */
        function checkForSemicolonForVariableDeclaration(node) {
            const parent = node.parent;

            if ((parent.type !== "ForStatement" || parent.init !== node) &&
                (!/^For(?:In|Of)Statement/.test(parent.type) || parent.left !== node)
            ) {
                checkForSemicolon(node);
            }
        }

        //--------------------------------------------------------------------------
        // Public API
        //--------------------------------------------------------------------------

        return {
            VariableDeclaration: checkForSemicolonForVariableDeclaration,
            ExpressionStatement: checkForSemicolon,
            ReturnStatement: checkForSemicolon,
            ThrowStatement: checkForSemicolon,
            DoWhileStatement: checkForSemicolon,
            DebuggerStatement: checkForSemicolon,
            BreakStatement: checkForSemicolon,
            ContinueStatement: checkForSemicolon,
            ImportDeclaration: checkForSemicolon,
            ExportAllDeclaration: checkForSemicolon,
            ExportNamedDeclaration(node) {
                if (!node.declaration) {
                    checkForSemicolon(node);
                }
            },
            ExportDefaultDeclaration(node) {
                if (!/(?:Class|Function)Declaration/.test(node.declaration.type)) {
                    checkForSemicolon(node);
                }
            }
        };

    }
};
