/**
 * @fileoverview extensions to TypeScript functionality around error handling
 * (ts.Diagnostics).
 */

import * as ts from 'typescript';

import {BazelOptions} from './tsconfig';

/**
 * If the current compilation was a compilation test expecting certain
 * diagnostics, filter out the expected diagnostics, and add new diagnostics
 * (aka errors) for non-matched diagnostics.
 */
export function filterExpected(
    bazelOpts: BazelOptions, diagnostics: ts.Diagnostic[],
    formatFn = uglyFormat): ts.Diagnostic[] {
  if (!bazelOpts.expectedDiagnostics.length) return diagnostics;

  // The regex contains two parts:
  // 1. Optional position: '\(5,1\)'
  // 2. Required TS error: 'TS2000: message text.'
  // Need triple escapes because the expected diagnostics that we're matching
  // here are regexes, too.
  const ERROR_RE = /^(?:\\\((\d*),(\d*)\\\).*)?TS(-?\d+):(.*)/;
  const incorrectErrors =
      bazelOpts.expectedDiagnostics.filter(e => !e.match(ERROR_RE));
  if (incorrectErrors.length) {
    const msg = `Expected errors must match regex ${ERROR_RE}\n\t` +
        `expected errors are "${incorrectErrors.join(', ')}"`;
    return [{
      file: undefined!,
      start: 0,
      length: 0,
      messageText: msg,
      category: ts.DiagnosticCategory.Error,
      code: 0,
    }];
  }

  // ExpectedDiagnostics represents the "expected_diagnostics" users provide in
  // the BUILD file. It is used for easier comparsion with the actual
  // diagnostics.
  interface ExpectedDiagnostics {
    line: number;
    column: number;
    expected: string;
    code: number;
    regexp: RegExp;
    matched: boolean;
  }

  const expectedDiags: ExpectedDiagnostics[] =
      bazelOpts.expectedDiagnostics.map(expected => {
        const m = expected.match(/^(?:\\\((\d*),(\d*)\\\).*)?TS(-?\d+):(.*)$/);
        if (!m) {
          throw new Error(
              'Incorrect expected error, did you forget character escapes in ' +
              expected);
        }
        const [, lineStr, columnStr, codeStr, regexp] = m;
        const [line, column, code] = [lineStr, columnStr, codeStr].map(str => {
          const i = Number(str);
          if (Number.isNaN(i)) {
            return 0;
          }
          return i;
        });
        return {
          line,
          column,
          expected,
          code,
          regexp: new RegExp(regexp),
          matched: false,
        };
      });

  const unmatchedDiags = diagnostics.filter(diag => {
    let line = -1;
    let character = -1;
    if (diag.file && diag.start) {
      ({line, character} =
           ts.getLineAndCharacterOfPosition(diag.file, diag.start));
    }
    let matched = false;
    const msg = formatFn(bazelOpts.target, [diag]);
    // checkDiagMatchesExpected checks if the expected diagnostics matches the
    // actual diagnostics.
    const checkDiagMatchesExpected =
        (expDiag: ExpectedDiagnostics, diag: ts.Diagnostic) => {
          if (expDiag.code !== diag.code || msg.search(expDiag.regexp) === -1) {
            return false;
          }
          // line and column are optional fields, only check them if they
          // are explicitly specified.
          // line and character are zero based.
          if (expDiag.line !== 0 && expDiag.line !== line + 1) {
            return false;
          }
          if (expDiag.column !== 0 && expDiag.column !== character + 1) {
            return false;
          }
          return true;
        };

    for (const expDiag of expectedDiags) {
      if (checkDiagMatchesExpected(expDiag, diag)) {
        expDiag.matched = true;
        matched = true;
        // continue, one diagnostic may match multiple expected errors.
      }
    }
    return !matched;
  });

  const unmatchedErrors = expectedDiags.filter(err => !err.matched).map(err => {
    const file = ts.createSourceFile(
        bazelOpts.target, '/* fake source as marker */',
        ts.ScriptTarget.Latest);
    const messageText =
        `Expected a compilation error matching ${JSON.stringify(err.expected)}`;
    return {
      file,
      start: 0,
      length: 0,
      messageText,
      category: ts.DiagnosticCategory.Error,
      code: err.code,
    };
  });

  return unmatchedDiags.concat(unmatchedErrors);
}

/**
 * Formats the given diagnostics, without pretty printing.  Without colors, it's
 * better for matching against programmatically.
 * @param target The bazel target, e.g. //my/package:target
 */
export function uglyFormat(
    target: string, diagnostics: ReadonlyArray<ts.Diagnostic>): string {
  const diagnosticsHost: ts.FormatDiagnosticsHost = {
    getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
    getNewLine: () => ts.sys.newLine,
    // Print filenames including their relativeRoot, so they can be located on
    // disk
    getCanonicalFileName: (f: string) => f
  };
  return ts.formatDiagnostics(diagnostics, diagnosticsHost);
}

/**
 * Pretty formats the given diagnostics (matching the --pretty tsc flag).
 * @param target The bazel target, e.g. //my/package:target
 */
export function format(
    target: string, diagnostics: ReadonlyArray<ts.Diagnostic>): string {
  const diagnosticsHost: ts.FormatDiagnosticsHost = {
    getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
    getNewLine: () => ts.sys.newLine,
    // Print filenames including their relativeRoot, so they can be located on
    // disk
    getCanonicalFileName: (f: string) => f
  };
  return ts.formatDiagnosticsWithColorAndContext(diagnostics, diagnosticsHost);
}
