import * as ts from 'typescript';
import {Checker} from '../../checker';
import {Fix} from '../../failure';
import {Fixer} from '../../util/fixer';
import {Config} from '../../util/pattern_config';
import {shouldExamineNode} from '../ast_tools';

/**
 * A patternEngine is the logic that handles a specific PatternKind.
 */
export abstract class PatternEngine {
  private readonly whitelistedPrefixes: string[] = [];
  private readonly whitelistedRegExps: RegExp[] = [];
  private readonly whitelistMemoizer: Map<string, boolean> = new Map();

  constructor(
      protected readonly config: Config, protected readonly fixer?: Fixer) {
    if (config.whitelistEntries) {
      for (const e of config.whitelistEntries) {
        if (e.prefix) {
          this.whitelistedPrefixes =
              this.whitelistedPrefixes.concat(...e.prefix);
        }
        if (e.regexp) {
          this.whitelistedRegExps = this.whitelistedRegExps.concat(
              ...e.regexp.map(r => new RegExp(r)));
        }
      }
    }
  }

  /**
   * `register` will be called by the ConformanceRule to tell Tsetse the
   * PatternEngine will handle matching. Implementations should use
   *`checkAndFilterResults` as a wrapper for `check`.
   **/
  abstract register(checker: Checker): void;

  /**
   * `check` is the PatternEngine subclass-specific matching logic. Overwrite
   * with what the engine looks for, i.e., AST matching. The whitelisting logic
   * and fix generation are handled in `checkAndFilterResults`.
   */
  abstract check(tc: ts.TypeChecker, n: ts.Node): ts.Node|undefined;

  /**
   * A wrapper for `check` that handles aspects of the analysis that are not
   * engine-specific, and which defers to the subclass-specific logic
   * afterwards.
   */
  checkAndFilterResults(c: Checker, n: ts.Node) {
    if (!shouldExamineNode(n) || n.getSourceFile().isDeclarationFile) {
      return;
    }
    const matchedNode = this.check(c.typeChecker, n);
    if (matchedNode && !this.isWhitelisted(matchedNode)) {
      const fix: Fix|undefined =
          this.fixer ? this.fixer.getFixForFlaggedNode(matchedNode) : undefined;
      c.addFailureAtNode(matchedNode, this.config.errorMessage, fix);
    }
  }

  isWhitelisted(n: ts.Node): boolean {
    const name: string = n.getSourceFile().fileName;
    if (this.whitelistMemoizer.has(name)) {
      return this.whitelistMemoizer.get(name)!;
    }
    for (const p of this.whitelistedPrefixes) {
      if (name.indexOf(p) == 0) {
        this.whitelistMemoizer.set(name, true);
        return true;
      }
    }
    for (const re of this.whitelistedRegExps) {
      if (re.test(name)) {
        this.whitelistMemoizer.set(name, true);
        return true;
      }
    }
    this.whitelistMemoizer.set(name, false);
    return false;
  }
}
