// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library fasta.stack_listener;

import 'dart:collection' show Queue;

import 'package:front_end/src/fasta/parser.dart' show ErrorKind, Listener;

import 'package:front_end/src/fasta/scanner.dart' show BeginGroupToken, Token;

import 'package:kernel/ast.dart' show AsyncMarker;

import '../errors.dart' show inputError, internalError;

import '../quote.dart' show unescapeString;

enum NullValue {
  Arguments,
  Block,
  BreakTarget,
  CascadeReceiver,
  Combinators,
  ConditionalUris,
  ContinueTarget,
  Expression,
  FieldInitializer,
  FormalParameters,
  FunctionBody,
  IdentifierList,
  Initializers,
  Metadata,
  Modifiers,
  SwitchScope,
  Type,
  TypeArguments,
  TypeList,
  TypeVariable,
  TypeVariables,
}

abstract class StackListener extends Listener {
  final Queue<Object> stack = new Queue<Object>();

  Uri get uri;

  // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart
  // and ast_builder.dart.
  void finishFunction(
      covariant formals, AsyncMarker asyncModifier, covariant body) {
    return internalError("Unsupported operation");
  }

  // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart
  // and ast_builder.dart.
  void exitLocalScope() => internalError("Unsupported operation");

  // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart
  // and ast_builder.dart.
  void prepareInitializers() => internalError("Unsupported operation");

  void push(Object node) {
    if (node == null) internalError("null not allowed.");
    stack.addLast(node);
  }

  Object peek() {
    Object node = stack.last;
    return node is NullValue ? null : node;
  }

  Object pop() {
    Object node = stack.removeLast();
    return node is NullValue ? null : node;
  }

  Object popIfNotNull(Object value) {
    return value == null ? null : pop();
  }

  List popList(int n) {
    if (n == 0) return null;
    List list = new List.filled(n, null, growable: true);
    for (int i = n - 1; i >= 0; i--) {
      list[i] = pop();
    }
    return list;
  }

  void debugEvent(String name) {
    // printEvent(name);
  }

  void printEvent(String name) {
    for (Object o in stack) {
      String s = "  $o";
      int index = s.indexOf("\n");
      if (index != -1) {
        s = s.substring(0, index) + "...";
      }
      print(s);
    }
    print(name);
  }

  @override
  void logEvent(String name) {
    internalError("Unhandled event: $name in $runtimeType $uri:\n"
        "  ${stack.join('\n  ')}");
  }

  @override
  void handleIdentifier(Token token) {
    debugEvent("handleIdentifier");
    push(token.value);
  }

  @override
  void endInitializer(Token token) {
    debugEvent("Initializer");
  }

  void checkEmpty() {
    if (stack.isNotEmpty) {
      internalError("${runtimeType}: Stack not empty $uri:\n"
          "  ${stack.join('\n  ')}");
    }
    if (recoverableErrors.isNotEmpty) {
      // TODO(ahe): Handle recoverable errors better.
      inputError(uri, recoverableErrors.first.beginOffset, recoverableErrors);
    }
  }

  @override
  void endTopLevelDeclaration(Token token) {
    debugEvent("TopLevelDeclaration");
    checkEmpty();
  }

  @override
  void endCompilationUnit(int count, Token token) {
    debugEvent("CompilationUnit");
    checkEmpty();
  }

  @override
  void handleNoTypeArguments(Token token) {
    debugEvent("NoTypeArguments");
    push(NullValue.TypeArguments);
  }

  @override
  void handleNoTypeVariables(Token token) {
    debugEvent("NoTypeVariables");
    push(NullValue.TypeVariables);
  }

  @override
  void handleNoType(Token token) {
    debugEvent("NoType");
    push(NullValue.Type);
  }

  @override
  void handleNoFormalParameters(Token token) {
    debugEvent("NoFormalParameters");
    push(NullValue.FormalParameters);
  }

  @override
  void handleNoArguments(Token token) {
    debugEvent("NoArguments");
    push(NullValue.Arguments);
  }

  @override
  void handleNoFunctionBody(Token token) {
    debugEvent("NoFunctionBody");
    push(NullValue.FunctionBody);
  }

  @override
  void handleNoInitializers() {
    debugEvent("NoInitializers");
    push(NullValue.Initializers);
  }

  @override
  void handleParenthesizedExpression(BeginGroupToken token) {
    debugEvent("ParenthesizedExpression");
  }

  @override
  void beginLiteralString(Token token) {
    debugEvent("beginLiteralString");
    push(token);
  }

  @override
  void endLiteralString(int interpolationCount) {
    debugEvent("endLiteralString");
    if (interpolationCount == 0) {
      Token token = pop();
      push(unescapeString(token.value));
    } else {
      internalError("String interpolation not implemented.");
    }
  }

  @override
  void handleStringJuxtaposition(int literalCount) {
    debugEvent("StringJuxtaposition");
    push(popList(literalCount).join(""));
  }

  @override
  void endCatchClause(Token token) {
    debugEvent("CatchClause");
  }

  @override
  void handleRecoverableError(Token token, ErrorKind kind, Map arguments) {
    super.handleRecoverableError(token, kind, arguments);
    debugEvent("Error: ${recoverableErrors.last}");
  }

  @override
  Token handleUnrecoverableError(Token token, ErrorKind kind, Map arguments) {
    throw inputError(uri, token.charOffset, "$kind $arguments");
  }
}
