/*
 Copyright 2015, Yahoo Inc.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */
'use strict';

const pathutils = require('./pathutils');
const {
    GREATEST_LOWER_BOUND,
    LEAST_UPPER_BOUND
} = require('source-map').SourceMapConsumer;

/**
 * AST ranges are inclusive for start positions and exclusive for end positions.
 * Source maps are also logically ranges over text, though interacting with
 * them is generally achieved by working with explicit positions.
 *
 * When finding the _end_ location of an AST item, the range behavior is
 * important because what we're asking for is the _end_ of whatever range
 * corresponds to the end location we seek.
 *
 * This boils down to the following steps, conceptually, though the source-map
 * library doesn't expose primitives to do this nicely:
 *
 * 1. Find the range on the generated file that ends at, or exclusively
 *    contains the end position of the AST node.
 * 2. Find the range on the original file that corresponds to
 *    that generated range.
 * 3. Find the _end_ location of that original range.
 */
function originalEndPositionFor(sourceMap, generatedEnd) {
    // Given the generated location, find the original location of the mapping
    // that corresponds to a range on the generated file that overlaps the
    // generated file end location. Note however that this position on its
    // own is not useful because it is the position of the _start_ of the range
    // on the original file, and we want the _end_ of the range.
    const beforeEndMapping = originalPositionTryBoth(
        sourceMap,
        generatedEnd.line,
        generatedEnd.column - 1
    );
    if (beforeEndMapping.source === null) {
        return null;
    }

    // Convert that original position back to a generated one, with a bump
    // to the right, and a rightward bias. Since 'generatedPositionFor' searches
    // for mappings in the original-order sorted list, this will find the
    // mapping that corresponds to the one immediately after the
    // beforeEndMapping mapping.
    const afterEndMapping = sourceMap.generatedPositionFor({
        source: beforeEndMapping.source,
        line: beforeEndMapping.line,
        column: beforeEndMapping.column + 1,
        bias: LEAST_UPPER_BOUND
    });
    if (
        // If this is null, it means that we've hit the end of the file,
        // so we can use Infinity as the end column.
        afterEndMapping.line === null ||
        // If these don't match, it means that the call to
        // 'generatedPositionFor' didn't find any other original mappings on
        // the line we gave, so consider the binding to extend to infinity.
        sourceMap.originalPositionFor(afterEndMapping).line !==
            beforeEndMapping.line
    ) {
        return {
            source: beforeEndMapping.source,
            line: beforeEndMapping.line,
            column: Infinity
        };
    }

    // Convert the end mapping into the real original position.
    return sourceMap.originalPositionFor(afterEndMapping);
}

/**
 * Attempts to determine the original source position, first
 * returning the closest element to the left (GREATEST_LOWER_BOUND),
 * and next returning the closest element to the right (LEAST_UPPER_BOUND).
 */
function originalPositionTryBoth(sourceMap, line, column) {
    const mapping = sourceMap.originalPositionFor({
        line,
        column,
        bias: GREATEST_LOWER_BOUND
    });
    if (mapping.source === null) {
        return sourceMap.originalPositionFor({
            line,
            column,
            bias: LEAST_UPPER_BOUND
        });
    } else {
        return mapping;
    }
}

function isInvalidPosition(pos) {
    return (
        !pos ||
        typeof pos.line !== 'number' ||
        typeof pos.column !== 'number' ||
        pos.line < 0 ||
        pos.column < 0
    );
}

/**
 * determines the original position for a given location
 * @param  {SourceMapConsumer} sourceMap the source map
 * @param  {Object} generatedLocation the original location Object
 * @returns {Object} the remapped location Object
 */
function getMapping(sourceMap, generatedLocation, origFile) {
    if (!generatedLocation) {
        return null;
    }

    if (
        isInvalidPosition(generatedLocation.start) ||
        isInvalidPosition(generatedLocation.end)
    ) {
        return null;
    }

    const start = originalPositionTryBoth(
        sourceMap,
        generatedLocation.start.line,
        generatedLocation.start.column
    );
    let end = originalEndPositionFor(sourceMap, generatedLocation.end);

    /* istanbul ignore if: edge case too hard to test for */
    if (!(start && end)) {
        return null;
    }

    if (!(start.source && end.source)) {
        return null;
    }

    if (start.source !== end.source) {
        return null;
    }

    /* istanbul ignore if: edge case too hard to test for */
    if (start.line === null || start.column === null) {
        return null;
    }

    /* istanbul ignore if: edge case too hard to test for */
    if (end.line === null || end.column === null) {
        return null;
    }

    if (start.line === end.line && start.column === end.column) {
        end = sourceMap.originalPositionFor({
            line: generatedLocation.end.line,
            column: generatedLocation.end.column,
            bias: LEAST_UPPER_BOUND
        });
        end.column -= 1;
    }

    return {
        source: pathutils.relativeTo(start.source, origFile),
        loc: {
            start: {
                line: start.line,
                column: start.column
            },
            end: {
                line: end.line,
                column: end.column
            }
        }
    };
}

module.exports = getMapping;
