// Copyright (c) 2020, 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.

import "dart:io" show File, Platform;
import "dart:typed_data" show Uint8List;

import "package:front_end/src/fasta/util/parser_ast.dart" show getAST;
import "package:front_end/src/fasta/util/parser_ast_helper.dart"
    show ParserAstNode, ParserAstType;

import "console_helper.dart";

void main(List<String> args) {
  Uri uri = Platform.script;
  if (args.isNotEmpty) {
    uri = Uri.base.resolve(args.first);
  }
  Uint8List bytes = new File.fromUri(uri).readAsBytesSync();
  ParserAstNode ast = getAST(bytes, enableExtensionMethods: true);

  Widget widget = new QuitOnQWidget(
    new WithSingleLineBottomWidget(
      new BoxedWidget(
        new AstWidget(ast),
      ),
      new StatusBarWidget(),
    ),
  );
  Application app = new Application(widget);
  app.start();
}

class PrintedLine {
  final String text;
  final ParserAstNode? ast;
  final List<PrintedLine>? parentShown;
  final int? selected;

  PrintedLine.parent(this.parentShown, this.selected)
      : text = "..",
        ast = null;

  PrintedLine.parentWithText(this.parentShown, this.text, this.selected)
      : ast = null;

  PrintedLine.ast(this.ast, this.text)
      : parentShown = null,
        selected = null;
}

class AstWidget extends Widget {
  late List<PrintedLine> shown;
  int selected = 0;

  AstWidget(ParserAstNode ast) {
    shown = [new PrintedLine.ast(ast, textualize(ast))];
  }

  String textualize(ParserAstNode element,
      {bool indent: false, bool withEndHeader: false}) {
    String header;
    switch (element.type) {
      case ParserAstType.BEGIN:
        header = "begin";
        break;
      case ParserAstType.HANDLE:
        header = "handle";
        break;
      case ParserAstType.END:
        header = withEndHeader ? "end" : "";
        break;
    }
    String extra = " ";
    if (element.children != null) {
      extra += element.children!.first.deprecatedArguments.toString();
    }
    return "${indent ? "  " : ""}"
        "${header}${element.what} "
        "${element.deprecatedArguments.toString()}${extra}";
  }

  @override
  void print(WriteOnlyOutput output) {
    for (int row = 0; row < shown.length; row++) {
      if (row >= output.rows) break;

      PrintedLine element = shown[row];
      String line = element.text;

      if (selected == row) {
        // Mark line with blue background.
        for (int column = 0; column < output.columns; column++) {
          output.setCell(row, column, backgroundColor: BackgroundColor.Blue);
        }
      }

      // Print text.
      int length = line.length;
      if (length > output.columns) {
        length = output.columns;
      }
      for (int column = 0; column < length; column++) {
        output.setCell(row, column, char: line[column]);
      }
    }
  }

  void enter() {
    // Enter selected line.
    PrintedLine selectedElement = shown[selected];
    if (selectedElement.parentShown != null) {
      shown = selectedElement.parentShown!;
      selected = selectedElement.selected!;
    } else {
      shown = [new PrintedLine.parent(shown, selected)];
      List<ParserAstNode>? children = selectedElement.ast!.children;
      if (children != null) {
        for (int i = 0; i < children.length; i++) {
          shown.add(new PrintedLine.ast(
              children[i], textualize(children[i], indent: i > 0)));
        }
      }
      shown.add(new PrintedLine.parentWithText(shown,
          textualize(selectedElement.ast!, withEndHeader: true), shown.length));
      selected = 0;
    }
  }

  @override
  bool input(_, List<int> data) {
    if (data.length > 2 &&
        data[0] == Application.CSI.codeUnitAt(0) &&
        data[1] == Application.CSI.codeUnitAt(1)) {
      // ANSI codes --- at least on my machine.
      if (data[2] == 65 /* A */) {
        // CSI _n_ A: Cursor Up (where n is optional defaulting to 1).
        // Up arrow.
        if (selected > 0) {
          selected--;
          return true;
        }
      } else if (data[2] == 66 /* B */) {
        // CSI _n_ B: Cursor Down (where n is optional defaulting to 1).
        // Down arrow.
        if (selected < shown.length - 1) {
          selected++;
          return true;
        }
      }
    } else if (data.length == 1 && data[0] == 10) {
      // <Return>.
      enter();
      return true;
    }
    return false;
  }
}

class StatusBarWidget extends Widget {
  List<int>? latestInput;

  @override
  void print(WriteOnlyOutput output) {
    // Paint everything with a red background.
    for (int row = 0; row < output.rows; row++) {
      for (int column = 0; column < output.columns; column++) {
        output.setCell(row, column, backgroundColor: BackgroundColor.Red);
      }
    }

    String leftString = "> ${latestInput ?? ""}";
    String rightString = "Press q or Ctrl-C to quit";
    for (int i = 0; i < leftString.length; i++) {
      output.setCell(0, i,
          char: leftString[i], backgroundColor: BackgroundColor.Red);
    }
    for (int i = 0; i < rightString.length; i++) {
      output.setCell(output.rows - 1, output.columns - rightString.length + i,
          char: rightString[i], backgroundColor: BackgroundColor.Red);
    }
  }

  @override
  bool input(Application app, List<int> data) {
    latestInput = data;
    return true;
  }
}
