// 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.

// @dart=2.9

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

import "package:front_end/src/fasta/util/direct_parser_ast.dart" show getAST;
import "package:front_end/src/fasta/util/direct_parser_ast_helper.dart"
    show DirectParserASTContent, DirectParserASTType;

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();
  DirectParserASTContent ast = getAST(bytes);

  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 DirectParserASTContent 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 {
  List<PrintedLine> shown;
  int selected = 0;

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

  String textualize(DirectParserASTContent element,
      {bool indent: false, bool withEndHeader: false}) {
    String header;
    switch (element.type) {
      case DirectParserASTType.BEGIN:
        header = "begin";
        break;
      case DirectParserASTType.HANDLE:
        header = "handle";
        break;
      case DirectParserASTType.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<DirectParserASTContent> 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;
  }
}
