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


import * as ts from 'typescript';

import {Failure} 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) {
    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);
    this.failures.push(failure);
  }

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

  /**
   * 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 = [];
    ts.forEachChild(sourceFile, run);
    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);
    }
  }
}
