/**
 * @fileoverview Disallow renaming import, export, and destructured assignments to the same name.
 * @author Kai Cataldo
 */

"use strict";

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

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

        docs: {
            description: "disallow renaming import, export, and destructured assignments to the same name",
            category: "ECMAScript 6",
            recommended: false,
            url: "https://eslint.org/docs/rules/no-useless-rename"
        },

        fixable: "code",

        schema: [
            {
                type: "object",
                properties: {
                    ignoreDestructuring: { type: "boolean", default: false },
                    ignoreImport: { type: "boolean", default: false },
                    ignoreExport: { type: "boolean", default: false }
                },
                additionalProperties: false
            }
        ]
    },

    create(context) {
        const options = context.options[0] || {},
            ignoreDestructuring = options.ignoreDestructuring === true,
            ignoreImport = options.ignoreImport === true,
            ignoreExport = options.ignoreExport === true;

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

        /**
         * Reports error for unnecessarily renamed assignments
         * @param {ASTNode} node - node to report
         * @param {ASTNode} initial - node with initial name value
         * @param {ASTNode} result - node with new name value
         * @param {string} type - the type of the offending node
         * @returns {void}
         */
        function reportError(node, initial, result, type) {
            const name = initial.type === "Identifier" ? initial.name : initial.value;

            return context.report({
                node,
                message: "{{type}} {{name}} unnecessarily renamed.",
                data: {
                    name,
                    type
                },
                fix(fixer) {
                    return fixer.replaceTextRange([
                        initial.range[0],
                        result.range[1]
                    ], name);
                }
            });
        }

        /**
         * Checks whether a destructured assignment is unnecessarily renamed
         * @param {ASTNode} node - node to check
         * @returns {void}
         */
        function checkDestructured(node) {
            if (ignoreDestructuring) {
                return;
            }

            const properties = node.properties;

            for (let i = 0; i < properties.length; i++) {
                if (properties[i].shorthand) {
                    continue;
                }

                /**
                 * If an ObjectPattern property is computed, we have no idea
                 * if a rename is useless or not. If an ObjectPattern property
                 * lacks a key, it is likely an ExperimentalRestProperty and
                 * so there is no "renaming" occurring here.
                 */
                if (properties[i].computed || !properties[i].key) {
                    continue;
                }

                if (properties[i].key.type === "Identifier" && properties[i].key.name === properties[i].value.name ||
                        properties[i].key.type === "Literal" && properties[i].key.value === properties[i].value.name) {
                    reportError(properties[i], properties[i].key, properties[i].value, "Destructuring assignment");
                }
            }
        }

        /**
         * Checks whether an import is unnecessarily renamed
         * @param {ASTNode} node - node to check
         * @returns {void}
         */
        function checkImport(node) {
            if (ignoreImport) {
                return;
            }

            if (node.imported.name === node.local.name &&
                    node.imported.range[0] !== node.local.range[0]) {
                reportError(node, node.imported, node.local, "Import");
            }
        }

        /**
         * Checks whether an export is unnecessarily renamed
         * @param {ASTNode} node - node to check
         * @returns {void}
         */
        function checkExport(node) {
            if (ignoreExport) {
                return;
            }

            if (node.local.name === node.exported.name &&
                    node.local.range[0] !== node.exported.range[0]) {
                reportError(node, node.local, node.exported, "Export");
            }

        }

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

        return {
            ObjectPattern: checkDestructured,
            ImportSpecifier: checkImport,
            ExportSpecifier: checkExport
        };
    }
};
