// Copyright (c) 2019, 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';
import 'dart:typed_data';

import 'package:front_end/src/fasta/parser.dart';
import 'package:front_end/src/fasta/parser/formal_parameter_kind.dart';
import 'package:front_end/src/fasta/parser/listener.dart';
import 'package:front_end/src/fasta/parser/member_kind.dart';
import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart';
import 'package:front_end/src/scanner/token.dart';
import 'package:dart_style/dart_style.dart' show DartFormatter;

StringSink out;

main(List<String> args) {
  if (args.contains("--stdout")) {
    out = stdout;
  } else {
    out = new StringBuffer();
  }

  File f = new File.fromUri(
      Platform.script.resolve("../lib/src/fasta/parser/listener.dart"));
  List<int> rawBytes = f.readAsBytesSync();

  Uint8List bytes = new Uint8List(rawBytes.length + 1);
  bytes.setRange(0, rawBytes.length, rawBytes);

  Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: true);
  Token firstToken = scanner.tokenize();

  out.write("""
// Copyright (c) 2019, 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 'package:front_end/src/fasta/messages.dart';
import 'package:front_end/src/fasta/parser/assert.dart';
import 'package:front_end/src/fasta/parser/declaration_kind.dart';
import 'package:front_end/src/fasta/parser/formal_parameter_kind.dart';
import 'package:front_end/src/fasta/parser/identifier_context.dart';
import 'package:front_end/src/fasta/parser/listener.dart';
import 'package:front_end/src/fasta/parser/member_kind.dart';
import 'package:front_end/src/fasta/scanner/error_token.dart';
import 'package:front_end/src/scanner/token.dart';

// THIS FILE IS AUTO GENERATED BY 'test/parser_test_listener_creator.dart'

class ParserTestListener implements Listener {
  int indent = 0;
  StringBuffer sb = new StringBuffer();

  void doPrint(String s) {
    sb.writeln(("  " * indent) + s);
  }
""");

  ParserCreatorListener listener = new ParserCreatorListener();
  ClassMemberParser parser = new ClassMemberParser(listener);
  parser.parseUnit(firstToken);

  out.writeln("}");

  if (out is StringBuffer) {
    stdout.write(new DartFormatter().format("$out"));
  }
}

class ParserCreatorListener extends Listener {
  bool insideListenerClass = false;
  String currentMethodName;
  List<String> parameters = <String>[];

  void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
    if (name.lexeme == "Listener") insideListenerClass = true;
  }

  void endClassDeclaration(Token beginToken, Token endToken) {
    insideListenerClass = false;
  }

  void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
      Token varFinalOrConst, Token getOrSet, Token name) {
    currentMethodName = name.lexeme;
  }

  void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
      Token beginInitializers, Token endToken) {
    if (insideListenerClass) {
      out.write("  ");
      Token token = beginToken;
      Token latestToken;
      while (true) {
        if (latestToken != null && latestToken.charEnd < token.charOffset) {
          out.write(" ");
        }
        out.write(token.lexeme);
        if ((token is BeginToken &&
                token.type == TokenType.OPEN_CURLY_BRACKET) ||
            token is SimpleToken && token.type == TokenType.FUNCTION) {
          break;
        }
        if (token == endToken) {
          throw token.runtimeType;
        }
        latestToken = token;
        token = token.next;
      }

      if (token is SimpleToken && token.type == TokenType.FUNCTION) {
        out.write(" null;");
      } else {
        out.write("\n    ");
        if (currentMethodName.startsWith("end")) {
          out.write("indent--;\n    ");
        }
        out.write("doPrint('$currentMethodName(");
        String separator = "";
        for (int i = 0; i < parameters.length; i++) {
          out.write(separator);
          out.write(r"' '$");
          out.write(parameters[i]);
          separator = ", ";
        }
        out.write(")');\n  ");

        if (currentMethodName.startsWith("begin")) {
          out.write("  indent++;\n  ");
        }

        out.write("}");
      }
      out.write("\n\n");
    }
    parameters.clear();
    currentMethodName = null;
  }

  void endFormalParameter(
      Token thisKeyword,
      Token periodAfterThis,
      Token nameToken,
      Token initializerStart,
      Token initializerEnd,
      FormalParameterKind kind,
      MemberKind memberKind) {
    parameters.add(nameToken.lexeme);
  }
}
