// Flags: --enable-source-maps
'use strict';

const common = require('../common');
const assert = require('assert');
const { findSourceMap, SourceMap } = require('module');
const { readFileSync } = require('fs');

// It should throw with invalid args.
{
  [1, true, 'foo'].forEach((invalidArg) =>
    assert.throws(
      () => new SourceMap(invalidArg),
      {
        code: 'ERR_INVALID_ARG_TYPE',
        name: 'TypeError',
        message: 'The "payload" argument must be of type object.' +
               common.invalidArgTypeHelper(invalidArg)
      }
    )
  );
}

// findSourceMap() can lookup source-maps based on URIs, in the
// non-exceptional case.
{
  require('../fixtures/source-map/disk-relative-path.js');
  const sourceMap = findSourceMap(
    require.resolve('../fixtures/source-map/disk-relative-path.js')
  );
  const {
    originalLine,
    originalColumn,
    originalSource
  } = sourceMap.findEntry(0, 29);
  assert.strictEqual(originalLine, 2);
  assert.strictEqual(originalColumn, 4);
  assert(originalSource.endsWith('disk.js'));
}

// findSourceMap() can be used in Error.prepareStackTrace() to lookup
// source-map attached to error.
{
  let callSite;
  let sourceMap;
  Error.prepareStackTrace = (error, trace) => {
    const throwingRequireCallSite = trace[0];
    if (throwingRequireCallSite.getFileName().endsWith('typescript-throw.js')) {
      sourceMap = findSourceMap(throwingRequireCallSite.getFileName());
      callSite = throwingRequireCallSite;
    }
  };
  try {
    // Require a file that throws an exception, and has a source map.
    require('../fixtures/source-map/typescript-throw.js');
  } catch (err) {
    // eslint-disable-next-line no-unused-expressions
    err.stack; // Force prepareStackTrace() to be called.
  }
  assert(callSite);
  assert(sourceMap);
  const {
    generatedLine,
    generatedColumn,
    originalLine,
    originalColumn,
    originalSource
  } = sourceMap.findEntry(
    callSite.getLineNumber() - 1,
    callSite.getColumnNumber() - 1
  );

  assert.strictEqual(generatedLine, 19);
  assert.strictEqual(generatedColumn, 14);

  assert.strictEqual(originalLine, 17);
  assert.strictEqual(originalColumn, 10);
  assert(originalSource.endsWith('typescript-throw.ts'));
}

// SourceMap can be instantiated with Source Map V3 object as payload.
{
  const payload = JSON.parse(readFileSync(
    require.resolve('../fixtures/source-map/disk.map'), 'utf8'
  ));
  const sourceMap = new SourceMap(payload);
  const {
    originalLine,
    originalColumn,
    originalSource
  } = sourceMap.findEntry(0, 29);
  assert.strictEqual(originalLine, 2);
  assert.strictEqual(originalColumn, 4);
  assert(originalSource.endsWith('disk.js'));
  // The stored payload should be a clone:
  assert.strictEqual(payload.mappings, sourceMap.payload.mappings);
  assert.notStrictEqual(payload, sourceMap.payload);
  assert.strictEqual(payload.sources[0], sourceMap.payload.sources[0]);
  assert.notStrictEqual(payload.sources, sourceMap.payload.sources);
}

// Test various known decodings to ensure decodeVLQ works correctly.
{
  function makeMinimalMap(column) {
    return {
      sources: ['test.js'],
      // Mapping from the 0th line, 0th column of the output file to the 0th
      // source file, 0th line, ${column}th column.
      mappings: `AAA${column}`,
    };
  }
  const knownDecodings = {
    'A': 0,
    'B': -2147483648,
    'C': 1,
    'D': -1,
    'E': 2,
    'F': -2,

    // 2^31 - 1, maximum values
    '+/////D': 2147483647,
    '8/////D': 2147483646,
    '6/////D': 2147483645,
    '4/////D': 2147483644,
    '2/////D': 2147483643,
    '0/////D': 2147483642,

    // -2^31 + 1, minimum values
    '//////D': -2147483647,
    '9/////D': -2147483646,
    '7/////D': -2147483645,
    '5/////D': -2147483644,
    '3/////D': -2147483643,
    '1/////D': -2147483642,
  };

  for (const column in knownDecodings) {
    const sourceMap = new SourceMap(makeMinimalMap(column));
    const { originalColumn } = sourceMap.findEntry(0, 0);
    assert.strictEqual(originalColumn, knownDecodings[column]);
  }
}

// Test that generated columns are sorted when a negative offset is
// observed, see: https://github.com/mozilla/source-map/pull/92
{
  function makeMinimalMap(generatedColumns, originalColumns) {
    return {
      sources: ['test.js'],
      // Mapping from the 0th line, ${g}th column of the output file to the 0th
      // source file, 0th line, ${column}th column.
      mappings: generatedColumns.map((g, i) => `${g}AA${originalColumns[i]}`)
        .join(',')
    };
  }
  // U = 10
  // F = -2
  // A = 0
  // E = 2
  const sourceMap = new SourceMap(makeMinimalMap(
    ['U', 'F', 'F'],
    ['A', 'E', 'E']
  ));
  assert.strictEqual(sourceMap.findEntry(0, 6).originalColumn, 4);
  assert.strictEqual(sourceMap.findEntry(0, 8).originalColumn, 2);
  assert.strictEqual(sourceMap.findEntry(0, 10).originalColumn, 0);
}
