/**
 * @fileoverview A helper that translates context.report() calls from the rule API into generic problem objects
 * @author Teddy Katz
 */

"use strict";

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

const assert = require("assert");
const ruleFixer = require("./util/rule-fixer");
const interpolate = require("./util/interpolate");

//------------------------------------------------------------------------------
// Typedefs
//------------------------------------------------------------------------------

/**
 * An error message description
 * @typedef {Object} MessageDescriptor
 * @property {ASTNode} [node] The reported node
 * @property {Location} loc The location of the problem.
 * @property {string} message The problem message.
 * @property {Object} [data] Optional data to use to fill in placeholders in the
 *      message.
 * @property {Function} [fix] The function to call that creates a fix command.
 */

/**
 * Information about the report
 * @typedef {Object} ReportInfo
 * @property {string} ruleId
 * @property {(0|1|2)} severity
 * @property {(string|undefined)} message
 * @property {(string|undefined)} messageId
 * @property {number} line
 * @property {number} column
 * @property {(number|undefined)} endLine
 * @property {(number|undefined)} endColumn
 * @property {(string|null)} nodeType
 * @property {string} source
 * @property {({text: string, range: (number[]|null)}|null)} fix
 */

//------------------------------------------------------------------------------
// Module Definition
//------------------------------------------------------------------------------


/**
 * Translates a multi-argument context.report() call into a single object argument call
 * @param {...*} arguments A list of arguments passed to `context.report`
 * @returns {MessageDescriptor} A normalized object containing report information
 */
function normalizeMultiArgReportCall() {

    // If there is one argument, it is considered to be a new-style call already.
    if (arguments.length === 1) {

        // Shallow clone the object to avoid surprises if reusing the descriptor
        return Object.assign({}, arguments[0]);
    }

    // If the second argument is a string, the arguments are interpreted as [node, message, data, fix].
    if (typeof arguments[1] === "string") {
        return {
            node: arguments[0],
            message: arguments[1],
            data: arguments[2],
            fix: arguments[3]
        };
    }

    // Otherwise, the arguments are interpreted as [node, loc, message, data, fix].
    return {
        node: arguments[0],
        loc: arguments[1],
        message: arguments[2],
        data: arguments[3],
        fix: arguments[4]
    };
}

/**
 * Asserts that either a loc or a node was provided, and the node is valid if it was provided.
 * @param {MessageDescriptor} descriptor A descriptor to validate
 * @returns {void}
 * @throws AssertionError if neither a node nor a loc was provided, or if the node is not an object
 */
function assertValidNodeInfo(descriptor) {
    if (descriptor.node) {
        assert(typeof descriptor.node === "object", "Node must be an object");
    } else {
        assert(descriptor.loc, "Node must be provided when reporting error if location is not provided");
    }
}

/**
 * Normalizes a MessageDescriptor to always have a `loc` with `start` and `end` properties
 * @param {MessageDescriptor} descriptor A descriptor for the report from a rule.
 * @returns {{start: Location, end: (Location|null)}} An updated location that infers the `start` and `end` properties
 * from the `node` of the original descriptor, or infers the `start` from the `loc` of the original descriptor.
 */
function normalizeReportLoc(descriptor) {
    if (descriptor.loc) {
        if (descriptor.loc.start) {
            return descriptor.loc;
        }
        return { start: descriptor.loc, end: null };
    }
    return descriptor.node.loc;
}

/**
 * Interpolates data placeholders in report messages
 * @param {MessageDescriptor} descriptor The report message descriptor.
 * @returns {string} The interpolated message for the descriptor
 */
function normalizeMessagePlaceholders(descriptor) {
    return interpolate(descriptor.message, descriptor.data);
}

/**
 * Compares items in a fixes array by range.
 * @param {Fix} a The first message.
 * @param {Fix} b The second message.
 * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
 * @private
 */
function compareFixesByRange(a, b) {
    return a.range[0] - b.range[0] || a.range[1] - b.range[1];
}

/**
 * Merges the given fixes array into one.
 * @param {Fix[]} fixes The fixes to merge.
 * @param {SourceCode} sourceCode The source code object to get the text between fixes.
 * @returns {{text: string, range: number[]}} The merged fixes
 */
function mergeFixes(fixes, sourceCode) {
    if (fixes.length === 0) {
        return null;
    }
    if (fixes.length === 1) {
        return fixes[0];
    }

    fixes.sort(compareFixesByRange);

    const originalText = sourceCode.text;
    const start = fixes[0].range[0];
    const end = fixes[fixes.length - 1].range[1];
    let text = "";
    let lastPos = Number.MIN_SAFE_INTEGER;

    for (const fix of fixes) {
        assert(fix.range[0] >= lastPos, "Fix objects must not be overlapped in a report.");

        if (fix.range[0] >= 0) {
            text += originalText.slice(Math.max(0, start, lastPos), fix.range[0]);
        }
        text += fix.text;
        lastPos = fix.range[1];
    }
    text += originalText.slice(Math.max(0, start, lastPos), end);

    return { range: [start, end], text };
}

/**
 * Gets one fix object from the given descriptor.
 * If the descriptor retrieves multiple fixes, this merges those to one.
 * @param {MessageDescriptor} descriptor The report descriptor.
 * @param {SourceCode} sourceCode The source code object to get text between fixes.
 * @returns {({text: string, range: number[]}|null)} The fix for the descriptor
 */
function normalizeFixes(descriptor, sourceCode) {
    if (typeof descriptor.fix !== "function") {
        return null;
    }

    // @type {null | Fix | Fix[] | IterableIterator<Fix>}
    const fix = descriptor.fix(ruleFixer);

    // Merge to one.
    if (fix && Symbol.iterator in fix) {
        return mergeFixes(Array.from(fix), sourceCode);
    }
    return fix;
}

/**
 * Creates information about the report from a descriptor
 * @param {Object} options Information about the problem
 * @param {string} options.ruleId Rule ID
 * @param {(0|1|2)} options.severity Rule severity
 * @param {(ASTNode|null)} options.node Node
 * @param {string} options.message Error message
 * @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location
 * @param {{text: string, range: (number[]|null)}} options.fix The fix object
 * @param {string[]} options.sourceLines Source lines
 * @returns {function(...args): ReportInfo} Function that returns information about the report
 */
function createProblem(options) {
    const problem = {
        ruleId: options.ruleId,
        severity: options.severity,
        message: options.message,
        line: options.loc.start.line,
        column: options.loc.start.column + 1,
        nodeType: options.node && options.node.type || null,
        source: options.sourceLines[options.loc.start.line - 1] || ""
    };

    /*
     * If this isn’t in the conditional, some of the tests fail
     * because `messageId` is present in the problem object
     */
    if (options.messageId) {
        problem.messageId = options.messageId;
    }

    if (options.loc.end) {
        problem.endLine = options.loc.end.line;
        problem.endColumn = options.loc.end.column + 1;
    }

    if (options.fix) {
        problem.fix = options.fix;
    }

    return problem;
}

/**
 * Returns a function that converts the arguments of a `context.report` call from a rule into a reported
 * problem for the Node.js API.
 * @param {{ruleId: string, severity: number, sourceCode: SourceCode, messageIds: Object}} metadata Metadata for the reported problem
 * @param {SourceCode} sourceCode The `SourceCode` instance for the text being linted
 * @returns {function(...args): ReportInfo} Function that returns information about the report
 */

module.exports = function createReportTranslator(metadata) {

    /*
     * `createReportTranslator` gets called once per enabled rule per file. It needs to be very performant.
     * The report translator itself (i.e. the function that `createReportTranslator` returns) gets
     * called every time a rule reports a problem, which happens much less frequently (usually, the vast
     * majority of rules don't report any problems for a given file).
     */
    return function() {
        const descriptor = normalizeMultiArgReportCall.apply(null, arguments);

        assertValidNodeInfo(descriptor);

        if (descriptor.messageId) {
            if (!metadata.messageIds) {
                throw new TypeError("context.report() called with a messageId, but no messages were present in the rule metadata.");
            }
            const id = descriptor.messageId;
            const messages = metadata.messageIds;

            if (descriptor.message) {
                throw new TypeError("context.report() called with a message and a messageId. Please only pass one.");
            }
            if (!messages || !Object.prototype.hasOwnProperty.call(messages, id)) {
                throw new TypeError(`context.report() called with a messageId of '${id}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`);
            }
            descriptor.message = messages[id];
        }


        return createProblem({
            ruleId: metadata.ruleId,
            severity: metadata.severity,
            node: descriptor.node,
            message: normalizeMessagePlaceholders(descriptor),
            messageId: descriptor.messageId,
            loc: normalizeReportLoc(descriptor),
            fix: normalizeFixes(descriptor, metadata.sourceCode),
            sourceLines: metadata.sourceCode.lines
        });
    };
};
