// 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/util/parser_ast.dart" show getAST;
import "package:front_end/src/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,
    enableTripleShift: true,
    allowPatterns: 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}";
  }

  int printLineFrom = 0;

  @override
  void print(WriteOnlyOutput output) {
    if (selected - printLineFrom >= output.rows) {
      // going down -- "scroll" so the selected line is at the bottom.
      printLineFrom = selected - output.rows + 1;
    } else if (selected - printLineFrom < 0) {
      // going up -- "scroll" so the selected line is at the top.
      printLineFrom = selected;
    }
    for (int row = printLineFrom; row < shown.length; row++) {
      if ((row - printLineFrom) >= 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 - printLineFrom, 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 - printLineFrom, 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;
  }
}
