/**
 * @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(nodeKind: ts.SyntaxKind.BinaryExpression,
     handlerFunction: (checker: Checker, node: ts.BinaryExpression) => void,
     code: number): void;
  on(nodeKind: ts.SyntaxKind.ConditionalExpression,
     handlerFunction:
         (checker: Checker, node: ts.ConditionalExpression) => void,
     code: number): void;
  on(nodeKind: ts.SyntaxKind.WhileStatement,
     handlerFunction: (checker: Checker, node: ts.WhileStatement) => void,
     code: number): void;
  on(nodeKind: ts.SyntaxKind.IfStatement,
     handlerFunction: (checker: Checker, node: ts.IfStatement) => void,
     code: number): void;
  on(nodeKind: ts.SyntaxKind.CallExpression,
     handlerFunction: (checker: Checker, node: ts.CallExpression) => void,
     code: number): void;
  on(nodeKind: ts.SyntaxKind.PropertyDeclaration,
     handlerFunction: (checker: Checker, node: ts.PropertyDeclaration) => void,
     code: number): void;
  on(nodeKind: ts.SyntaxKind.ElementAccessExpression,
     handlerFunction: (checker: Checker, node: ts.ElementAccessExpression) => void,
     code: number): void;
  on(nodeKind: ts.SyntaxKind.ImportDeclaration,
     handlerFunction: (checker: Checker, node: ts.ImportDeclaration) => void,
     code: number): void;
  on(nodeKind: ts.SyntaxKind,
     handlerFunction: (checker: Checker, node: ts.Node) => void,
     code: number): void;
  on<T extends ts.Node>(
      nodeKind: ts.SyntaxKind,
      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);
    }
  }
}
