/**
 * @fileoverview Checker contains all the information we need to perform source
 * file AST traversals and report errors.
 */

import * as ts from 'typescript';
import {Failure, Fix} from './failure';


/**
 * A Handler contains a handler function and its corresponding error code so
 * when the handler function is triggered we know which rule is violated.
 */
interface Handler {
  handlerFunction(checker: Checker, node: ts.Node): void;
  code: number;
}

/**
 * Tsetse rules use on() and addFailureAtNode() for rule implementations.
 * Rules can get a ts.TypeChecker from checker.typeChecker so typed rules are
 * possible. Compiler uses execute() to run the Tsetse check.
 */
export class Checker {
  /**
   * nodeHandlersMap contains node to handlers mapping for all enabled rules.
   */
  private nodeHandlersMap = new Map<ts.SyntaxKind, Handler[]>();
  private failures: Failure[] = [];
  private currentSourceFile: ts.SourceFile|undefined;
  // currentCode will be set before invoking any handler functions so the value
  // initialized here is never used.
  private currentCode = 0;
  /**
   * Allow typed rules via typeChecker.
   */
  typeChecker: ts.TypeChecker;

  constructor(program: ts.Program) {
    // Avoid the cost for each rule to create a new TypeChecker.
    this.typeChecker = program.getTypeChecker();
  }

  /**
   * This doesn't run any checks yet. Instead, it registers `handlerFunction` on
   * `nodeKind` node in `nodeHandlersMap` map. After all rules register their
   * handlers, the source file AST will be traversed.
   */
  on<T extends ts.Node>(
      nodeKind: T['kind'], handlerFunction: (checker: Checker, node: T) => void,
      code: number) {
    const newHandler: Handler = {handlerFunction, code};
    const registeredHandlers: Handler[]|undefined =
        this.nodeHandlersMap.get(nodeKind);
    if (registeredHandlers === undefined) {
      this.nodeHandlersMap.set(nodeKind, [newHandler]);
    } else {
      registeredHandlers.push(newHandler);
    }
  }

  /**
   * Add a failure with a span. addFailure() is currently private because
   * `addFailureAtNode` is preferred.
   */
  private addFailure(
      start: number, end: number, failureText: string, fix?: Fix) {
    if (!this.currentSourceFile) {
      throw new Error('Source file not defined');
    }
    if (start >= end || end > this.currentSourceFile.end || start < 0) {
      // Since only addFailureAtNode() is exposed for now this shouldn't happen.
      throw new Error(
          `Invalid start and end position: [${start}, ${end}]` +
          ` in file ${this.currentSourceFile.fileName}.`);
    }

    const failure = new Failure(
        this.currentSourceFile, start, end, failureText, this.currentCode, fix);
    this.failures.push(failure);
  }

  addFailureAtNode(node: ts.Node, failureText: string, fix?: Fix) {
    // node.getStart() takes a sourceFile as argument whereas node.getEnd()
    // doesn't need it.
    this.addFailure(
        node.getStart(this.currentSourceFile), node.getEnd(), failureText, fix);
  }

  /**
   * Walk `sourceFile`, invoking registered handlers with Checker as the first
   * argument and current node as the second argument. Return failures if there
   * are any.
   */
  execute(sourceFile: ts.SourceFile): Failure[] {
    const thisChecker = this;
    this.currentSourceFile = sourceFile;
    this.failures = [];
    run(sourceFile);
    return this.failures;

    function run(node: ts.Node) {
      const handlers: Handler[]|undefined =
          thisChecker.nodeHandlersMap.get(node.kind);
      if (handlers !== undefined) {
        for (const handler of handlers) {
          thisChecker.currentCode = handler.code;
          handler.handlerFunction(thisChecker, node);
        }
      }
      ts.forEachChild(node, run);
    }
  }
}
