import 'jasmine';

import * as crypto from 'crypto';
import * as fs from 'fs';
import * as os from 'os';
import * as ts from 'typescript';

import {Checker} from '../../checker';
import {Failure, Fix} from '../../failure';
import {AbstractRule} from '../../rule';


function compile(...sourceCode: string[]): ts.Program {
  const temporaryFolder = os.tmpdir() +
      `/tslint_test_input_${crypto.randomBytes(16).toString('hex')}`;
  const fullPaths: string[] = [];
  sourceCode.forEach((s, i) => {
    fullPaths.push(`${temporaryFolder}/file_${i}.ts`);
  });

  let error: Error|undefined = undefined;
  let program: ts.Program|undefined = undefined;
  try {  // Wrap it all in a try/finally to clean up the temp files afterwards
    fs.mkdirSync(temporaryFolder);
    sourceCode.forEach((s, i) => {
      fs.writeFileSync(fullPaths[i], s);
    });
    program = ts.createProgram(fullPaths, {});
    if (ts.getPreEmitDiagnostics(program).length !== 0) {
      throw new Error(
          'Your program does not compile cleanly. Diagnostics:\n' +
          ts.formatDiagnostics(
              ts.getPreEmitDiagnostics(program), ts.createCompilerHost({})));
    }
  } catch (e) {
    error = e;
  } finally {
    fullPaths.forEach(p => fs.unlinkSync(p));
    fs.rmdirSync(temporaryFolder);
  }
  if (program && !error) {
    return program;
  } else {
    throw error;
  }
}

function check(rule: AbstractRule, program: ts.Program): Failure[] {
  const checker = new Checker(program);
  rule.register(checker);
  return program.getSourceFiles()
      .map(s => checker.execute(s))
      .reduce((prev, cur) => prev.concat(cur));
}

/** Builds and run the given Rule upon the source files that were provided. */
export function compileAndCheck(
    rule: AbstractRule, ...sourceCode: string[]): Failure[] {
  const program = compile(...sourceCode);
  return check(rule, program);
}

// Custom matcher for Jasmine, for a better experience matching fixes.
export const customMatchers: jasmine.CustomMatcherFactories = {
  toBeFailureMatching(): jasmine.CustomMatcher {
    return {
      compare: (actual: ts.Diagnostic&{end: number, fix?: Fix}, exp: {
        fileName?: string, start: number, end: number,
      }) => {
        let regrets = '';
        if (exp === undefined) {
          regrets += 'The rule requires two arguments. ';
        }
        if (exp.fileName) {
          if (!actual.file) {
            regrets += 'Expected diagnostic to have a source file. ';
          } else if (!actual.file.fileName.endsWith(exp.fileName)) {
            regrets += `Expected ${actual.file.fileName} to end with ${
                exp.fileName}. `;
          }
        }
        if (exp.start && actual.start !== exp.start) {
          regrets += expectation('start', exp.start, actual.start);
        }
        if (exp.end && actual.end !== exp.end) {
          regrets += expectation('end', exp.end, actual.end);
        }
        return {pass: regrets === '', message: regrets};
      }
    };
  }
};

function expectation(fieldname: string, expectation: any, actual: any) {
  return `Expected .${fieldname} to be ${expectation}, was ${actual}. `;
}

// And the matching type
declare global {
  namespace jasmine {
    interface Matchers<T> {
      toBeFailureMatching(expected: {
        fileName?: string,
                start: number,
                end: number,
                [i: string]: any  // the rest
      }): void;
    }
  }
}
