/**
 * @fileoverview Rule to flag no-unneeded-ternary
 * @author Gyandeep Singh
 */

"use strict";

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

// Operators that always result in a boolean value
const BOOLEAN_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<=", "in", "instanceof"]);
const OPERATOR_INVERSES = {
    "==": "!=",
    "!=": "==",
    "===": "!==",
    "!==": "==="

    // Operators like < and >= are not true inverses, since both will return false with NaN.
};
const OR_PRECEDENCE = astUtils.getPrecedence({ type: "LogicalExpression", operator: "||" });

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

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

        docs: {
            description: "disallow ternary operators when simpler alternatives exist",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/no-unneeded-ternary"
        },

        schema: [
            {
                type: "object",
                properties: {
                    defaultAssignment: {
                        type: "boolean",
                        default: true
                    }
                },
                additionalProperties: false
            }
        ],

        fixable: "code"
    },

    create(context) {
        const options = context.options[0] || {};
        const defaultAssignment = options.defaultAssignment !== false;
        const sourceCode = context.getSourceCode();

        /**
         * Test if the node is a boolean literal
         * @param {ASTNode} node - The node to report.
         * @returns {boolean} True if the its a boolean literal
         * @private
         */
        function isBooleanLiteral(node) {
            return node.type === "Literal" && typeof node.value === "boolean";
        }

        /**
         * Creates an expression that represents the boolean inverse of the expression represented by the original node
         * @param {ASTNode} node A node representing an expression
         * @returns {string} A string representing an inverted expression
         */
        function invertExpression(node) {
            if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) {
                const operatorToken = sourceCode.getFirstTokenBetween(
                    node.left,
                    node.right,
                    token => token.value === node.operator
                );
                const text = sourceCode.getText();

                return text.slice(node.range[0],
                    operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + text.slice(operatorToken.range[1], node.range[1]);
            }

            if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) {
                return `!(${astUtils.getParenthesisedText(sourceCode, node)})`;
            }
            return `!${astUtils.getParenthesisedText(sourceCode, node)}`;
        }

        /**
         * Tests if a given node always evaluates to a boolean value
         * @param {ASTNode} node - An expression node
         * @returns {boolean} True if it is determined that the node will always evaluate to a boolean value
         */
        function isBooleanExpression(node) {
            return node.type === "BinaryExpression" && BOOLEAN_OPERATORS.has(node.operator) ||
                node.type === "UnaryExpression" && node.operator === "!";
        }

        /**
         * Test if the node matches the pattern id ? id : expression
         * @param {ASTNode} node - The ConditionalExpression to check.
         * @returns {boolean} True if the pattern is matched, and false otherwise
         * @private
         */
        function matchesDefaultAssignment(node) {
            return node.test.type === "Identifier" &&
                   node.consequent.type === "Identifier" &&
                   node.test.name === node.consequent.name;
        }

        return {

            ConditionalExpression(node) {
                if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) {
                    context.report({
                        node,
                        loc: node.consequent.loc.start,
                        message: "Unnecessary use of boolean literals in conditional expression.",
                        fix(fixer) {
                            if (node.consequent.value === node.alternate.value) {

                                // Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true`
                                return node.test.type === "Identifier" ? fixer.replaceText(node, node.consequent.value.toString()) : null;
                            }
                            if (node.alternate.value) {

                                // Replace `foo() ? false : true` with `!(foo())`
                                return fixer.replaceText(node, invertExpression(node.test));
                            }

                            // Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise.

                            return fixer.replaceText(node, isBooleanExpression(node.test) ? astUtils.getParenthesisedText(sourceCode, node.test) : `!${invertExpression(node.test)}`);
                        }
                    });
                } else if (!defaultAssignment && matchesDefaultAssignment(node)) {
                    context.report({
                        node,
                        loc: node.consequent.loc.start,
                        message: "Unnecessary use of conditional expression for default assignment.",
                        fix: fixer => {
                            const shouldParenthesizeAlternate = (
                                astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE &&
                                !astUtils.isParenthesised(sourceCode, node.alternate)
                            );
                            const alternateText = shouldParenthesizeAlternate
                                ? `(${sourceCode.getText(node.alternate)})`
                                : astUtils.getParenthesisedText(sourceCode, node.alternate);
                            const testText = astUtils.getParenthesisedText(sourceCode, node.test);

                            return fixer.replaceText(node, `${testText} || ${alternateText}`);
                        }
                    });
                }
            }
        };
    }
};
