/**
 * @fileoverview Rule to require or disallow newlines between statements
 * @author Toru Nagashima
 */

"use strict";

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

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

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

const LT = `[${Array.from(astUtils.LINEBREAKS).join("")}]`;
const PADDING_LINE_SEQUENCE = new RegExp(
    String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`
);
const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/;
const CJS_IMPORT = /^require\(/;

/**
 * Creates tester which check if a node starts with specific keyword.
 *
 * @param {string} keyword The keyword to test.
 * @returns {Object} the created tester.
 * @private
 */
function newKeywordTester(keyword) {
    return {
        test: (node, sourceCode) =>
            sourceCode.getFirstToken(node).value === keyword
    };
}

/**
 * Creates tester which check if a node is specific type.
 *
 * @param {string} type The node type to test.
 * @returns {Object} the created tester.
 * @private
 */
function newNodeTypeTester(type) {
    return {
        test: node =>
            node.type === type
    };
}

/**
 * Checks the given node is an expression statement of IIFE.
 *
 * @param {ASTNode} node The node to check.
 * @returns {boolean} `true` if the node is an expression statement of IIFE.
 * @private
 */
function isIIFEStatement(node) {
    if (node.type === "ExpressionStatement") {
        let call = node.expression;

        if (call.type === "UnaryExpression") {
            call = call.argument;
        }
        return call.type === "CallExpression" && astUtils.isFunction(call.callee);
    }
    return false;
}

/**
 * Checks whether the given node is a block-like statement.
 * This checks the last token of the node is the closing brace of a block.
 *
 * @param {SourceCode} sourceCode The source code to get tokens.
 * @param {ASTNode} node The node to check.
 * @returns {boolean} `true` if the node is a block-like statement.
 * @private
 */
function isBlockLikeStatement(sourceCode, node) {

    // do-while with a block is a block-like statement.
    if (node.type === "DoWhileStatement" && node.body.type === "BlockStatement") {
        return true;
    }

    /*
     * IIFE is a block-like statement specially from
     * JSCS#disallowPaddingNewLinesAfterBlocks.
     */
    if (isIIFEStatement(node)) {
        return true;
    }

    // Checks the last token is a closing brace of blocks.
    const lastToken = sourceCode.getLastToken(node, astUtils.isNotSemicolonToken);
    const belongingNode = lastToken && astUtils.isClosingBraceToken(lastToken)
        ? sourceCode.getNodeByRangeIndex(lastToken.range[0])
        : null;

    return Boolean(belongingNode) && (
        belongingNode.type === "BlockStatement" ||
        belongingNode.type === "SwitchStatement"
    );
}

/**
 * Check whether the given node is a directive or not.
 * @param {ASTNode} node The node to check.
 * @param {SourceCode} sourceCode The source code object to get tokens.
 * @returns {boolean} `true` if the node is a directive.
 */
function isDirective(node, sourceCode) {
    return (
        node.type === "ExpressionStatement" &&
        (
            node.parent.type === "Program" ||
            (
                node.parent.type === "BlockStatement" &&
                astUtils.isFunction(node.parent.parent)
            )
        ) &&
        node.expression.type === "Literal" &&
        typeof node.expression.value === "string" &&
        !astUtils.isParenthesised(sourceCode, node.expression)
    );
}

/**
 * Check whether the given node is a part of directive prologue or not.
 * @param {ASTNode} node The node to check.
 * @param {SourceCode} sourceCode The source code object to get tokens.
 * @returns {boolean} `true` if the node is a part of directive prologue.
 */
function isDirectivePrologue(node, sourceCode) {
    if (isDirective(node, sourceCode)) {
        for (const sibling of node.parent.body) {
            if (sibling === node) {
                break;
            }
            if (!isDirective(sibling, sourceCode)) {
                return false;
            }
        }
        return true;
    }
    return false;
}

/**
 * Gets the actual last token.
 *
 * If a semicolon is semicolon-less style's semicolon, this ignores it.
 * For example:
 *
 *     foo()
 *     ;[1, 2, 3].forEach(bar)
 *
 * @param {SourceCode} sourceCode The source code to get tokens.
 * @param {ASTNode} node The node to get.
 * @returns {Token} The actual last token.
 * @private
 */
function getActualLastToken(sourceCode, node) {
    const semiToken = sourceCode.getLastToken(node);
    const prevToken = sourceCode.getTokenBefore(semiToken);
    const nextToken = sourceCode.getTokenAfter(semiToken);
    const isSemicolonLessStyle = Boolean(
        prevToken &&
        nextToken &&
        prevToken.range[0] >= node.range[0] &&
        astUtils.isSemicolonToken(semiToken) &&
        semiToken.loc.start.line !== prevToken.loc.end.line &&
        semiToken.loc.end.line === nextToken.loc.start.line
    );

    return isSemicolonLessStyle ? prevToken : semiToken;
}

/**
 * This returns the concatenation of the first 2 captured strings.
 * @param {string} _ Unused. Whole matched string.
 * @param {string} trailingSpaces The trailing spaces of the first line.
 * @param {string} indentSpaces The indentation spaces of the last line.
 * @returns {string} The concatenation of trailingSpaces and indentSpaces.
 * @private
 */
function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) {
    return trailingSpaces + indentSpaces;
}

/**
 * Check and report statements for `any` configuration.
 * It does nothing.
 *
 * @returns {void}
 * @private
 */
function verifyForAny() {
}

/**
 * Check and report statements for `never` configuration.
 * This autofix removes blank lines between the given 2 statements.
 * However, if comments exist between 2 blank lines, it does not remove those
 * blank lines automatically.
 *
 * @param {RuleContext} context The rule context to report.
 * @param {ASTNode} _ Unused. The previous node to check.
 * @param {ASTNode} nextNode The next node to check.
 * @param {Array<Token[]>} paddingLines The array of token pairs that blank
 * lines exist between the pair.
 * @returns {void}
 * @private
 */
function verifyForNever(context, _, nextNode, paddingLines) {
    if (paddingLines.length === 0) {
        return;
    }

    context.report({
        node: nextNode,
        message: "Unexpected blank line before this statement.",
        fix(fixer) {
            if (paddingLines.length >= 2) {
                return null;
            }

            const prevToken = paddingLines[0][0];
            const nextToken = paddingLines[0][1];
            const start = prevToken.range[1];
            const end = nextToken.range[0];
            const text = context.getSourceCode().text
                .slice(start, end)
                .replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines);

            return fixer.replaceTextRange([start, end], text);
        }
    });
}

/**
 * Check and report statements for `always` configuration.
 * This autofix inserts a blank line between the given 2 statements.
 * If the `prevNode` has trailing comments, it inserts a blank line after the
 * trailing comments.
 *
 * @param {RuleContext} context The rule context to report.
 * @param {ASTNode} prevNode The previous node to check.
 * @param {ASTNode} nextNode The next node to check.
 * @param {Array<Token[]>} paddingLines The array of token pairs that blank
 * lines exist between the pair.
 * @returns {void}
 * @private
 */
function verifyForAlways(context, prevNode, nextNode, paddingLines) {
    if (paddingLines.length > 0) {
        return;
    }

    context.report({
        node: nextNode,
        message: "Expected blank line before this statement.",
        fix(fixer) {
            const sourceCode = context.getSourceCode();
            let prevToken = getActualLastToken(sourceCode, prevNode);
            const nextToken = sourceCode.getFirstTokenBetween(
                prevToken,
                nextNode,
                {
                    includeComments: true,

                    /**
                     * Skip the trailing comments of the previous node.
                     * This inserts a blank line after the last trailing comment.
                     *
                     * For example:
                     *
                     *     foo(); // trailing comment.
                     *     // comment.
                     *     bar();
                     *
                     * Get fixed to:
                     *
                     *     foo(); // trailing comment.
                     *
                     *     // comment.
                     *     bar();
                     *
                     * @param {Token} token The token to check.
                     * @returns {boolean} `true` if the token is not a trailing comment.
                     * @private
                     */
                    filter(token) {
                        if (astUtils.isTokenOnSameLine(prevToken, token)) {
                            prevToken = token;
                            return false;
                        }
                        return true;
                    }
                }
            ) || nextNode;
            const insertText = astUtils.isTokenOnSameLine(prevToken, nextToken)
                ? "\n\n"
                : "\n";

            return fixer.insertTextAfter(prevToken, insertText);
        }
    });
}

/**
 * Types of blank lines.
 * `any`, `never`, and `always` are defined.
 * Those have `verify` method to check and report statements.
 * @private
 */
const PaddingTypes = {
    any: { verify: verifyForAny },
    never: { verify: verifyForNever },
    always: { verify: verifyForAlways }
};

/**
 * Types of statements.
 * Those have `test` method to check it matches to the given statement.
 * @private
 */
const StatementTypes = {
    "*": { test: () => true },
    "block-like": {
        test: (node, sourceCode) => isBlockLikeStatement(sourceCode, node)
    },
    "cjs-export": {
        test: (node, sourceCode) =>
            node.type === "ExpressionStatement" &&
            node.expression.type === "AssignmentExpression" &&
            CJS_EXPORT.test(sourceCode.getText(node.expression.left))
    },
    "cjs-import": {
        test: (node, sourceCode) =>
            node.type === "VariableDeclaration" &&
            node.declarations.length > 0 &&
            Boolean(node.declarations[0].init) &&
            CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init))
    },
    directive: {
        test: isDirectivePrologue
    },
    expression: {
        test: (node, sourceCode) =>
            node.type === "ExpressionStatement" &&
            !isDirectivePrologue(node, sourceCode)
    },
    "multiline-block-like": {
        test: (node, sourceCode) =>
            node.loc.start.line !== node.loc.end.line &&
            isBlockLikeStatement(sourceCode, node)
    },
    "multiline-expression": {
        test: (node, sourceCode) =>
            node.loc.start.line !== node.loc.end.line &&
            node.type === "ExpressionStatement" &&
            !isDirectivePrologue(node, sourceCode)
    },

    block: newNodeTypeTester("BlockStatement"),
    empty: newNodeTypeTester("EmptyStatement"),

    break: newKeywordTester("break"),
    case: newKeywordTester("case"),
    class: newKeywordTester("class"),
    const: newKeywordTester("const"),
    continue: newKeywordTester("continue"),
    debugger: newKeywordTester("debugger"),
    default: newKeywordTester("default"),
    do: newKeywordTester("do"),
    export: newKeywordTester("export"),
    for: newKeywordTester("for"),
    function: newKeywordTester("function"),
    if: newKeywordTester("if"),
    import: newKeywordTester("import"),
    let: newKeywordTester("let"),
    return: newKeywordTester("return"),
    switch: newKeywordTester("switch"),
    throw: newKeywordTester("throw"),
    try: newKeywordTester("try"),
    var: newKeywordTester("var"),
    while: newKeywordTester("while"),
    with: newKeywordTester("with")
};

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

module.exports = {
    meta: {
        docs: {
            description: "require or disallow padding lines between statements",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/padding-line-between-statements"
        },
        fixable: "whitespace",
        schema: {
            definitions: {
                paddingType: {
                    enum: Object.keys(PaddingTypes)
                },
                statementType: {
                    anyOf: [
                        { enum: Object.keys(StatementTypes) },
                        {
                            type: "array",
                            items: { enum: Object.keys(StatementTypes) },
                            minItems: 1,
                            uniqueItems: true,
                            additionalItems: false
                        }
                    ]
                }
            },
            type: "array",
            items: {
                type: "object",
                properties: {
                    blankLine: { $ref: "#/definitions/paddingType" },
                    prev: { $ref: "#/definitions/statementType" },
                    next: { $ref: "#/definitions/statementType" }
                },
                additionalProperties: false,
                required: ["blankLine", "prev", "next"]
            },
            additionalItems: false
        }
    },

    create(context) {
        const sourceCode = context.getSourceCode();
        const configureList = context.options || [];
        let scopeInfo = null;

        /**
         * Processes to enter to new scope.
         * This manages the current previous statement.
         * @returns {void}
         * @private
         */
        function enterScope() {
            scopeInfo = {
                upper: scopeInfo,
                prevNode: null
            };
        }

        /**
         * Processes to exit from the current scope.
         * @returns {void}
         * @private
         */
        function exitScope() {
            scopeInfo = scopeInfo.upper;
        }

        /**
         * Checks whether the given node matches the given type.
         *
         * @param {ASTNode} node The statement node to check.
         * @param {string|string[]} type The statement type to check.
         * @returns {boolean} `true` if the statement node matched the type.
         * @private
         */
        function match(node, type) {
            let innerStatementNode = node;

            while (innerStatementNode.type === "LabeledStatement") {
                innerStatementNode = innerStatementNode.body;
            }
            if (Array.isArray(type)) {
                return type.some(match.bind(null, innerStatementNode));
            }
            return StatementTypes[type].test(innerStatementNode, sourceCode);
        }

        /**
         * Finds the last matched configure from configureList.
         *
         * @param {ASTNode} prevNode The previous statement to match.
         * @param {ASTNode} nextNode The current statement to match.
         * @returns {Object} The tester of the last matched configure.
         * @private
         */
        function getPaddingType(prevNode, nextNode) {
            for (let i = configureList.length - 1; i >= 0; --i) {
                const configure = configureList[i];
                const matched =
                    match(prevNode, configure.prev) &&
                    match(nextNode, configure.next);

                if (matched) {
                    return PaddingTypes[configure.blankLine];
                }
            }
            return PaddingTypes.any;
        }

        /**
         * Gets padding line sequences between the given 2 statements.
         * Comments are separators of the padding line sequences.
         *
         * @param {ASTNode} prevNode The previous statement to count.
         * @param {ASTNode} nextNode The current statement to count.
         * @returns {Array<Token[]>} The array of token pairs.
         * @private
         */
        function getPaddingLineSequences(prevNode, nextNode) {
            const pairs = [];
            let prevToken = getActualLastToken(sourceCode, prevNode);

            if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
                do {
                    const token = sourceCode.getTokenAfter(
                        prevToken,
                        { includeComments: true }
                    );

                    if (token.loc.start.line - prevToken.loc.end.line >= 2) {
                        pairs.push([prevToken, token]);
                    }
                    prevToken = token;

                } while (prevToken.range[0] < nextNode.range[0]);
            }

            return pairs;
        }

        /**
         * Verify padding lines between the given node and the previous node.
         *
         * @param {ASTNode} node The node to verify.
         * @returns {void}
         * @private
         */
        function verify(node) {
            const parentType = node.parent.type;
            const validParent =
                astUtils.STATEMENT_LIST_PARENTS.has(parentType) ||
                parentType === "SwitchStatement";

            if (!validParent) {
                return;
            }

            // Save this node as the current previous statement.
            const prevNode = scopeInfo.prevNode;

            // Verify.
            if (prevNode) {
                const type = getPaddingType(prevNode, node);
                const paddingLines = getPaddingLineSequences(prevNode, node);

                type.verify(context, prevNode, node, paddingLines);
            }

            scopeInfo.prevNode = node;
        }

        /**
         * Verify padding lines between the given node and the previous node.
         * Then process to enter to new scope.
         *
         * @param {ASTNode} node The node to verify.
         * @returns {void}
         * @private
         */
        function verifyThenEnterScope(node) {
            verify(node);
            enterScope();
        }

        return {
            Program: enterScope,
            BlockStatement: enterScope,
            SwitchStatement: enterScope,
            "Program:exit": exitScope,
            "BlockStatement:exit": exitScope,
            "SwitchStatement:exit": exitScope,

            ":statement": verify,

            SwitchCase: verifyThenEnterScope,
            "SwitchCase:exit": exitScope
        };
    }
};
