import 'jasmine';

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

import {Checker} from '../../checker';
import {Failure, fixToString} from '../../failure';
import {AbstractRule} from '../../rule';
import {Config} from '../pattern_config';



/**
 * Turns the provided source (as strings) into a ts.Program. The source files
 * will be named `.../file_${n}.ts`, with n the index of the source file in
 * the `sourceCode` array.
 */
export function compile(...sourceCode: string[]): ts.Program {
  const temporaryFolder = os.tmpdir() + path.sep +
      `tslint_test_input_${crypto.randomBytes(16).toString('hex')}`;
  const fullPaths: string[] = [];
  sourceCode.forEach((s, i) => {
    fullPaths.push(`${temporaryFolder}${path.sep}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);
}

/** Turns a Failure to a fileName. */
export function toFileName(f: Failure) {
  const file = f.toDiagnostic().file;
  return file ? file.fileName : 'unknown';
}

export function getTempDirForWhitelist() {
  // TS uses forward slashes on Windows ¯\_(ツ)_/¯
  return os.platform() == 'win32' ? os.tmpdir().replace(/\\/g, '/') :
                                    os.tmpdir();
}

// Custom matcher for Jasmine, for a better experience matching fixes.
export const customMatchers: jasmine.CustomMatcherFactories = {

  toHaveNFailures(): jasmine.CustomMatcher {
    return {
      compare: (actual: Failure[], expected: Number, config?: Config) => {
        if (actual.length === expected) {
          return {pass: true};
        } else {
          let message =
              `Expected ${expected} Failures, but found ${actual.length}.`;
          if (actual.length) {
            message += '\n' + actual.map(f => f.toString()).join('\n');
          }
          if (config) {
            message += `\nConfig: {kind:${config.kind}, values:${
                JSON.stringify(config.values)}, whitelist:${
                JSON.stringify(config.whitelistEntries)} }`;
          }
          return {pass: false, message};
        }
      }
    };
  },

  toBeFailureMatching(): jasmine.CustomMatcher {
    return {
      compare: (actualFailure: Failure, exp: {
        fileName?: string,
        start?: number,
        end?: number,
        matchedCode?: string,
        messageText?: string,
      }) => {
        const actualDiagnostic = actualFailure.toDiagnostic();
        let regrets = '';
        if (exp === undefined) {
          regrets += 'The matcher requires two arguments. ';
        }
        if (exp.fileName) {
          if (!actualDiagnostic.file) {
            regrets += `Expected diagnostic to have a source file, but it had ${
                actualDiagnostic.file}. `;
          } else if (!actualDiagnostic.file.fileName.endsWith(exp.fileName)) {
            regrets += `Expected ${
                actualDiagnostic.file.fileName} to end with ${exp.fileName}. `;
          }
        }
        if (exp.messageText !== undefined &&
            exp.messageText != actualDiagnostic.messageText) {
          regrets += expectation(
              'errorMessage', exp.messageText, actualDiagnostic.messageText);
        }
        if (exp.start !== undefined && actualDiagnostic.start !== exp.start) {
          regrets += expectation('start', exp.start, actualDiagnostic.start);
        }
        if (exp.end !== undefined && actualDiagnostic.end !== exp.end) {
          regrets += expectation('end', exp.end, actualDiagnostic.end);
        }
        if (exp.matchedCode) {
          if (!actualDiagnostic.file) {
            regrets += `Expected diagnostic to have a source file, but it had ${
                actualDiagnostic.file}. `;
          } else if (actualDiagnostic.start === undefined) {
            // I don't know how this could happen, but typings say so.
            regrets += `Expected diagnostic to have a starting position. `;
          } else {
            const foundMatchedCode = actualDiagnostic.file.getFullText().slice(
                Number(actualDiagnostic.start), actualDiagnostic.end);
            if (foundMatchedCode != exp.matchedCode) {
              regrets += `Expected diagnostic to match ${
                  exp.matchedCode}, but was ${foundMatchedCode} (from ${
                  Number(
                      actualDiagnostic.start)} to ${actualDiagnostic.end}). `;
            }
          }
        }
        return {pass: regrets === '', message: regrets};
      }
    };
  },

  /** Checks that a Failure has the expected Fix field. */
  toHaveFixMatching(): jasmine.CustomMatcher {
    return {
      compare: (actualFailure: Failure, exp: [{
                  fileName?: string,
                  start?: number,
                  end?: number,
                  replacement?: string
                }]) => {
        let regrets = '';
        const actualFix = actualFailure.toDiagnostic().fix;
        if (!actualFix) {
          regrets += `Expected ${actualFailure.toString()} to have fix ${
              JSON.stringify(exp)}. `;
        } else if (actualFix.changes.length != exp.length) {
          regrets += `Expected ${exp.length} individual changes, got ${
              actualFix.changes.length}. `;
          if (actualFix.changes.length) {
            regrets += '\n' + fixToString(actualFix);
          }
        } else {
          for (let i = 0; i < exp.length; i++) {
            const e = exp[i];
            const a = actualFix.changes[i];
            if (e.start !== undefined && e.start !== a.start) {
              regrets += expectation(
                  `${i}th individualChange's start`, e.start, a.start);
            }
            if (e.end !== undefined && e.end !== a.end) {
              regrets +=
                  expectation(`${i}th individualChange's end`, e.end, a.end);
            }
            if (e.replacement !== undefined &&
                e.replacement !== a.replacement) {
              regrets += expectation(
                  `${i}th individualChange's replacement`, e.replacement,
                  a.replacement);
            }
            if (e.fileName !== undefined &&
                e.fileName !== a.sourceFile.fileName) {
              regrets += expectation(
                  `${i}th individualChange's fileName`, e.fileName,
                  a.sourceFile.fileName);
            }
            // TODO: Consider adding matchedCode as for the failure matcher.
          }
        }

        return {pass: regrets === '', message: regrets};
      }
    };
  },

  /**
   * Asserts that a Failure has no fix.
   */
  toHaveNoFix(): jasmine.CustomMatcher {
    return {
      compare: (actualFailure: Failure) => {
        return {
          pass: actualFailure.toDiagnostic().fix === undefined,
          message: 'This failure should not have a fix.'
        };
      }
    };
  }

};

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,
        matchedCode?: string,
        messageText?: string,
      }): void;

      /** Checks that a Failure has the expected Fix field. */
      toHaveFixMatching(expected: [
        {fileName?: string, start?: number, end?: number, replacement?: string}
      ]): void;

      toHaveNFailures(expected: Number, config?: Config): void;

      /** Asserts that a Failure has no fix. */
      toHaveNoFix(): void;
    }
  }
}
