import 'jasmine';
import * as ts from 'typescript';
import {Failure, Fix} from '../../failure';
import {ConformancePatternRule, PatternKind} from '../../rules/conformance_pattern_rule';
import {buildReplacementFixer, Fixer, maybeAddNamedImport, maybeAddNamespaceImport} from '../../util/fixer';
import {compile, compileAndCheck, customMatchers} from '../../util/testing/test_support';

const uppercaseFixer: Fixer = {
  getFixForFlaggedNode(node: ts.Node): Fix {
    return {
      changes: [{
        start: node.getStart(),
        end: node.getEnd(),
        replacement: node.getText().toUpperCase(),
        sourceFile: node.getSourceFile(),
      }]
    };
  }
};

const uppercaseFixerBuilt: Fixer = buildReplacementFixer((node: ts.Node) => {
  return {replaceWith: node.getText().toUpperCase()};
})

// The initial config and source off which we run those checks.
const baseConfig = {
  errorMessage: 'found citation',
  kind: PatternKind.BANNED_PROPERTY_WRITE,
  values: ['HTMLQuoteElement.prototype.cite'],
};

const source = `export {};\n` +
    `const q = document.createElement('q');\n` +
    `q.cite = 'some example string';\n`;

describe('ConformancePatternRule\'s fixer', () => {
  describe('Generates basic fixes', () => {
    it('for a single match', () => {
      const rule = new ConformancePatternRule(baseConfig, uppercaseFixer);
      const results = compileAndCheck(rule, source);

      expect(results).toHaveNFailures(1, baseConfig);
      expect(results[0]).toBeFailureMatching({
        matchedCode: `q.cite = 'some example string'`,
        messageText: 'found citation'
      });
      expect(results[0]).toHaveFixMatching([
        {start: 50, end: 80, replacement: `Q.CITE = 'SOME EXAMPLE STRING'`}
      ]);
    });

    it('for a single match (alternate fixer)', () => {
      const rule = new ConformancePatternRule(baseConfig, uppercaseFixerBuilt);
      const results = compileAndCheck(rule, source);

      expect(results).toHaveNFailures(1, baseConfig);
      expect(results[0]).toBeFailureMatching({
        matchedCode: `q.cite = 'some example string'`,
        messageText: 'found citation'
      });
      expect(results[0]).toHaveFixMatching([
        {start: 50, end: 80, replacement: `Q.CITE = 'SOME EXAMPLE STRING'`}
      ]);
    });

    it('for several matches', () => {
      const rule = new ConformancePatternRule(baseConfig, uppercaseFixer);
      const sourceTwoMatches =
          source + `q.cite = 'some other example string';\n`;
      const results = compileAndCheck(rule, sourceTwoMatches);

      expect(results).toHaveNFailures(2, baseConfig);
      expect(results[0]).toBeFailureMatching({
        matchedCode: `q.cite = 'some example string'`,
        messageText: 'found citation'
      });
      expect(results[1]).toBeFailureMatching({
        matchedCode: `q.cite = 'some other example string'`,
        messageText: 'found citation'
      });
      expect(results[0]).toHaveFixMatching([
        {start: 50, end: 80, replacement: `Q.CITE = 'SOME EXAMPLE STRING'`}
      ]);
      expect(results[0].fixToReadableStringInContext())
          .toBe(
              `Suggested fix:\n` +
              `- Replace the full match with: Q.CITE = 'SOME EXAMPLE STRING'`);
      expect(results[1]).toHaveFixMatching([{
        start: 82,
        end: 118,
        replacement: `Q.CITE = 'SOME OTHER EXAMPLE STRING'`
      }]);
      expect(results[1].fixToReadableStringInContext())
          .toBe(
              `Suggested fix:\n` +
              `- Replace the full match with: Q.CITE = 'SOME OTHER EXAMPLE STRING'`);
    });
  });

  describe('adds imports', () => {
    const addNamedImportFixer: Fixer = {
      getFixForFlaggedNode(n: ts.Node) {
        const ic =
            maybeAddNamedImport(n.getSourceFile(), 'foo', './file_1', 'bar');
        if (ic) return {changes: [ic]};
        return;
      }
    };

    it('maybeAddNamedImport additions', () => {
      const results = compileAndCheck(
          new ConformancePatternRule(baseConfig, addNamedImportFixer), source);

      expect(results[0]).toHaveFixMatching([{
        start: 0,
        end: 0,
        replacement: `import {foo as bar} from './file_1';\n`
      }]);
      expect(results[0].fixToReadableStringInContext())
          .toBe(
              `Suggested fix:\n` +
              `- Add new import: import {foo as bar} from './file_1';`);
    });

    it('maybeAddNamedImport already there', () => {
      const results = compileAndCheck(
          new ConformancePatternRule(baseConfig, addNamedImportFixer),
          'import {foo as bar} from \'./file_1\';\n' + source,
          'export const foo = 1;');

      expect(results[0]).toHaveNoFix();
      expect(results[0].fixToReadableStringInContext()).toBe('');
    });

    it('maybeAddNamedImport different name', () => {
      const results = compileAndCheck(
          new ConformancePatternRule(baseConfig, addNamedImportFixer),
          'import {foo as baz} from \'./file_1\';\n' + source,
          'export const foo = 1;');

      expect(results[0]).toHaveFixMatching([
        {start: 8, end: 8, replacement: `foo as bar, `}
      ]);
      expect(results[0].fixToReadableStringInContext())
          .toBe(
              `Suggested fix:\n` +
              `- Insert at line 1, char 9: foo as bar,`);
    });

    it('maybeAddNamespacedImport', () => {
      const addNamespacedImportFixer: Fixer = {
        getFixForFlaggedNode(n: ts.Node): Fix |
        undefined {
          const ic =
              maybeAddNamespaceImport(n.getSourceFile(), './file_1', 'foo');
          if (ic) return {changes: [ic]};
          return;
        }
      };
      const results = compileAndCheck(
          new ConformancePatternRule(baseConfig, addNamespacedImportFixer),
          source);

      expect(results[0]).toHaveFixMatching([
        {start: 0, end: 0, replacement: `import * as foo from './file_1';\n`}
      ]);
    });
  });

  describe('the logic for location->text transforms', () => {
    const sourceFile = compile(`let a;\nlet b;\n`)
                           .getSourceFiles()
                           .filter(f => f.fileName.indexOf('file_0') !== -1)[0];
    // let a;\nlet b;\n
    // 0123456 7890123  Positions
    // 1234567 1234567  Expected result in characters

    it('stringifies as expected', () => {
      // Only the sourceFile matters here.
      const failure = new Failure(sourceFile, NaN, NaN, 'whatever', NaN);

      expect(failure.readableRange(0, 0)).toBe('at line 1, char 1');
      expect(failure.readableRange(1, 1)).toBe('at line 1, char 2');
      expect(failure.readableRange(0, 1)).toBe('line 1, from char 1 to 2');
      expect(failure.readableRange(0, 1)).toBe('line 1, from char 1 to 2');
      expect(failure.readableRange(7, 7)).toBe('at line 2, char 1');
      expect(failure.readableRange(0, 7))
          .toBe('from line 1, char 1 to line 2, char 1');
    });
  });
});



beforeEach(() => {
  jasmine.addMatchers(customMatchers);
});
