// Copyright (c) 2017, 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, exitCode;

import "package:_fe_analyzer_shared/src/messages/severity.dart"
    show severityEnumNames;

import 'package:dart_style/dart_style.dart' show DartFormatter;

import 'package:yaml/yaml.dart' show loadYaml;

import '../../test/utils/io_utils.dart' show computeRepoDirUri;

main(List<String> arguments) {
  final Uri repoDir = computeRepoDirUri();
  Messages message = generateMessagesFiles(repoDir);
  if (message.sharedMessages.trim().isEmpty ||
      message.cfeMessages.trim().isEmpty) {
    print("Bailing because of errors: "
        "Refusing to overwrite with empty file!");
  } else {
    new File.fromUri(computeSharedGeneratedFile(repoDir))
        .writeAsStringSync(message.sharedMessages, flush: true);
    new File.fromUri(computeCfeGeneratedFile(repoDir))
        .writeAsStringSync(message.cfeMessages, flush: true);
  }
}

Uri computeSharedGeneratedFile(Uri repoDir) {
  return repoDir
      .resolve("pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart");
}

Uri computeCfeGeneratedFile(Uri repoDir) {
  return repoDir
      .resolve("pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart");
}

class Messages {
  final String sharedMessages;
  final String cfeMessages;

  Messages(this.sharedMessages, this.cfeMessages);
}

Messages generateMessagesFiles(Uri repoDir) {
  Uri messagesFile = repoDir.resolve("pkg/front_end/messages.yaml");
  Map<dynamic, dynamic> yaml =
      loadYaml(new File.fromUri(messagesFile).readAsStringSync());
  StringBuffer sharedMessages = new StringBuffer();
  StringBuffer cfeMessages = new StringBuffer();

  const String preamble1 = """
// Copyright (c) 2021, 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.

""";

  const String preamble2 = """

// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'pkg/front_end/messages.yaml' and run
// 'pkg/front_end/tool/fasta generate-messages' to update.

// ignore_for_file: lines_longer_than_80_chars
""";

  sharedMessages.writeln(preamble1);
  sharedMessages.writeln(preamble2);
  sharedMessages.writeln("""
part of _fe_analyzer_shared.messages.codes;
""");

  cfeMessages.writeln(preamble1);
  cfeMessages.writeln("""

""");
  cfeMessages.writeln(preamble2);
  cfeMessages.writeln("""
part of fasta.codes;
""");

  bool hasError = false;
  int largestIndex = 0;
  final indexNameMap = new Map<int, String>();

  List<String> keys = yaml.keys.cast<String>().toList()..sort();
  for (String name in keys) {
    var description = yaml[name];
    while (description is String) {
      description = yaml[description];
    }
    Map<dynamic, dynamic> map = description;
    if (map == null) {
      throw "No 'template:' in key $name.";
    }
    var index = map['index'];
    if (index != null) {
      if (index is! int || index < 1) {
        print('Error: Expected positive int for "index:" field in $name,'
            ' but found $index');
        hasError = true;
        index = -1;
        // Continue looking for other problems.
      } else {
        String otherName = indexNameMap[index];
        if (otherName != null) {
          print('Error: The "index:" field must be unique, '
              'but is the same for $otherName and $name');
          hasError = true;
          // Continue looking for other problems.
        } else {
          indexNameMap[index] = name;
          if (largestIndex < index) {
            largestIndex = index;
          }
        }
      }
    }
    Template template = compileTemplate(name, index, map['template'],
        map['tip'], map['analyzerCode'], map['severity']);
    if (template.isShared) {
      sharedMessages.writeln(template.text);
    } else {
      cfeMessages.writeln(template.text);
    }
  }
  if (largestIndex > indexNameMap.length) {
    print('Error: The "index:" field values should be unique, consecutive'
        ' whole numbers starting with 1.');
    hasError = true;
    // Fall through to print more information.
  }
  if (hasError) {
    exitCode = 1;
    print('The largest index is $largestIndex');
    final sortedIndices = indexNameMap.keys.toList()..sort();
    int nextAvailableIndex = largestIndex + 1;
    for (int index = 1; index <= sortedIndices.length; ++index) {
      if (sortedIndices[index - 1] != index) {
        nextAvailableIndex = index;
        break;
      }
    }
    print('The next available index is ${nextAvailableIndex}');
    return new Messages('', '');
  }

  return new Messages(new DartFormatter().format("$sharedMessages"),
      new DartFormatter().format("$cfeMessages"));
}

final RegExp placeholderPattern =
    new RegExp("#\([-a-zA-Z0-9_]+\)(?:%\([0-9]*\)\.\([0-9]+\))?");

class Template {
  final String text;
  final isShared;

  Template(this.text, {this.isShared}) : assert(isShared != null);
}

Template compileTemplate(String name, int index, String template, String tip,
    Object analyzerCode, String severity) {
  if (template == null) {
    print('Error: missing template for message: $name');
    exitCode = 1;
    return new Template('', isShared: true);
  }
  // Remove trailing whitespace. This is necessary for templates defined with
  // `|` (verbatim) as they always contain a trailing newline that we don't
  // want.
  template = template.trimRight();
  const String ignoreNotNull = "// ignore: unnecessary_null_comparison";
  var parameters = new Set<String>();
  var conversions = new Set<String>();
  var conversions2 = new Set<String>();
  var arguments = new Set<String>();
  bool hasLabeler = false;
  bool canBeShared = true;
  void ensureLabeler() {
    if (hasLabeler) return;
    conversions
        .add("TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);");
    hasLabeler = true;
    canBeShared = false;
  }

  for (Match match
      in placeholderPattern.allMatches("$template\n${tip ?? ''}")) {
    String name = match[1];
    String padding = match[2];
    String fractionDigits = match[3];

    String format(String name) {
      String conversion;
      if (fractionDigits == null) {
        conversion = "'\$$name'";
      } else {
        conversion = "$name.toStringAsFixed($fractionDigits)";
      }
      if (padding.isNotEmpty) {
        if (padding.startsWith("0")) {
          conversion += ".padLeft(${int.parse(padding)}, '0')";
        } else {
          conversion += ".padLeft(${int.parse(padding)})";
        }
      }
      return conversion;
    }

    switch (name) {
      case "character":
        parameters.add("String character");
        conversions.add("if (character.runes.length != 1)"
            "throw \"Not a character '\${character}'\";");
        arguments.add("'$name': character");
        break;

      case "unicode":
        // Write unicode value using at least four (but otherwise no more than
        // necessary) hex digits, using uppercase letters.
        // http://www.unicode.org/versions/Unicode10.0.0/appA.pdf
        parameters.add("int codePoint");
        conversions.add("String unicode = \"U+\${codePoint.toRadixString(16)"
            ".toUpperCase().padLeft(4, '0')}\";");
        arguments.add("'$name': codePoint");
        break;

      case "name":
        parameters.add("String name");
        conversions.add("if (name.isEmpty) throw 'No name provided';");
        arguments.add("'$name': name");
        conversions.add("name = demangleMixinApplicationName(name);");
        break;

      case "name2":
        parameters.add("String name2");
        conversions.add("if (name2.isEmpty) throw 'No name provided';");
        arguments.add("'$name': name2");
        conversions.add("name2 = demangleMixinApplicationName(name2);");
        break;

      case "name3":
        parameters.add("String name3");
        conversions.add("if (name3.isEmpty) throw 'No name provided';");
        arguments.add("'$name': name3");
        conversions.add("name3 = demangleMixinApplicationName(name3);");
        break;

      case "name4":
        parameters.add("String name4");
        conversions.add("if (name4.isEmpty) throw 'No name provided';");
        arguments.add("'$name': name4");
        conversions.add("name4 = demangleMixinApplicationName(name4);");
        break;

      case "nameOKEmpty":
        parameters.add("String nameOKEmpty");
        conversions.add("$ignoreNotNull\n"
            "if (nameOKEmpty == null || nameOKEmpty.isEmpty) "
            "nameOKEmpty = '(unnamed)';");
        arguments.add("'nameOKEmpty': nameOKEmpty");
        break;

      case "names":
        parameters.add("List<String> _names");
        conversions.add("if (_names.isEmpty) throw 'No names provided';");
        arguments.add("'$name': _names");
        conversions.add("String names = itemizeNames(_names);");
        break;

      case "lexeme":
        parameters.add("Token token");
        conversions.add("String lexeme = token.lexeme;");
        arguments.add("'$name': token");
        break;

      case "lexeme2":
        parameters.add("Token token2");
        conversions.add("String lexeme2 = token2.lexeme;");
        arguments.add("'$name': token2");
        break;

      case "string":
        parameters.add("String string");
        conversions.add("if (string.isEmpty) throw 'No string provided';");
        arguments.add("'$name': string");
        break;

      case "string2":
        parameters.add("String string2");
        conversions.add("if (string2.isEmpty) throw 'No string provided';");
        arguments.add("'$name': string2");
        break;

      case "string3":
        parameters.add("String string3");
        conversions.add("if (string3.isEmpty) throw 'No string provided';");
        arguments.add("'$name': string3");
        break;

      case "stringOKEmpty":
        parameters.add("String stringOKEmpty");
        conversions.add("$ignoreNotNull\n"
            "if (stringOKEmpty == null || stringOKEmpty.isEmpty) "
            "stringOKEmpty = '(empty)';");
        arguments.add("'$name': stringOKEmpty");
        break;

      case "type":
      case "type2":
      case "type3":
      case "type4":
        parameters.add("DartType _${name}");
        ensureLabeler();
        conversions
            .add("List<Object> ${name}Parts = labeler.labelType(_${name});");
        conversions2.add("String ${name} = ${name}Parts.join();");
        arguments.add("'${name}': _${name}");
        break;

      case "uri":
        parameters.add("Uri uri_");
        conversions.add("String? uri = relativizeUri(uri_);");
        arguments.add("'$name': uri_");
        break;

      case "uri2":
        parameters.add("Uri uri2_");
        conversions.add("String? uri2 = relativizeUri(uri2_);");
        arguments.add("'$name': uri2_");
        break;

      case "uri3":
        parameters.add("Uri uri3_");
        conversions.add("String? uri3 = relativizeUri(uri3_);");
        arguments.add("'$name': uri3_");
        break;

      case "count":
        parameters.add("int count");
        conversions.add(
            "$ignoreNotNull\n" "if (count == null) throw 'No count provided';");
        arguments.add("'$name': count");
        break;

      case "count2":
        parameters.add("int count2");
        conversions.add("$ignoreNotNull\n"
            "if (count2 == null) throw 'No count provided';");
        arguments.add("'$name': count2");
        break;

      case "constant":
        parameters.add("Constant _constant");
        ensureLabeler();
        conversions.add(
            "List<Object> ${name}Parts = labeler.labelConstant(_${name});");
        conversions2.add("String ${name} = ${name}Parts.join();");
        arguments.add("'$name': _constant");
        break;

      case "num1":
        parameters.add("num _num1");
        conversions.add("$ignoreNotNull\n"
            "if (_num1 == null) throw 'No number provided';");
        conversions.add("String num1 = ${format('_num1')};");
        arguments.add("'$name': _num1");
        break;

      case "num2":
        parameters.add("num _num2");
        conversions.add("$ignoreNotNull\n"
            "if (_num2 == null) throw 'No number provided';");
        conversions.add("String num2 = ${format('_num2')};");
        arguments.add("'$name': _num2");
        break;

      case "num3":
        parameters.add("num _num3");
        conversions.add("$ignoreNotNull\n"
            "if (_num3 == null) throw 'No number provided';");
        conversions.add("String num3 = ${format('_num3')};");
        arguments.add("'$name': _num3");
        break;

      default:
        throw "Unhandled placeholder in template: '$name'";
    }
  }

  if (hasLabeler) {
    parameters.add("bool isNonNullableByDefault");
  }

  conversions.addAll(conversions2);

  String interpolate(String text) {
    text = text
        .replaceAll(r"$", r"\$")
        .replaceAllMapped(placeholderPattern, (Match m) => "\${${m[1]}}");
    return "\"\"\"$text\"\"\"";
  }

  List<String> codeArguments = <String>[];
  if (index != null) {
    codeArguments.add('index: $index');
  } else if (analyzerCode != null) {
    if (analyzerCode is String) {
      analyzerCode = <String>[analyzerCode];
    }
    List<Object> codes = analyzerCode;
    // If "index:" is defined, then "analyzerCode:" should not be generated
    // in the front end. See comment in messages.yaml
    codeArguments.add('analyzerCodes: <String>["${codes.join('", "')}"]');
  }
  if (severity != null) {
    String severityEnumName = severityEnumNames[severity];
    if (severityEnumName == null) {
      throw "Unknown severity '$severity'";
    }
    codeArguments.add('severity: Severity.$severityEnumName');
  }

  if (parameters.isEmpty && conversions.isEmpty && arguments.isEmpty) {
    if (template != null) {
      codeArguments.add('message: r"""$template"""');
    }
    if (tip != null) {
      codeArguments.add('tip: r"""$tip"""');
    }

    return new Template("""
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> code$name = message$name;

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode message$name =
    const MessageCode(\"$name\", ${codeArguments.join(', ')});
""", isShared: canBeShared);
  }

  List<String> templateArguments = <String>[];
  if (template != null) {
    templateArguments.add('messageTemplate: r"""$template"""');
  }
  if (tip != null) {
    templateArguments.add('tipTemplate: r"""$tip"""');
  }

  templateArguments.add("withArguments: _withArguments$name");

  List<String> messageArguments = <String>[];
  String message = interpolate(template);
  if (hasLabeler) {
    message += " + labeler.originMessages";
  }
  messageArguments.add("message: ${message}");
  if (tip != null) {
    messageArguments.add("tip: ${interpolate(tip)}");
  }
  messageArguments.add("arguments: { ${arguments.join(', ')} }");

  return new Template("""
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(${parameters.join(', ')})> template$name =
    const Template<Message Function(${parameters.join(', ')})>(
        ${templateArguments.join(', ')});

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(${parameters.join(', ')})> code$name =
    const Code<Message Function(${parameters.join(', ')})>(
        \"$name\", ${codeArguments.join(', ')});

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArguments$name(${parameters.join(', ')}) {
  ${conversions.join('\n  ')}
  return new Message(
     code$name,
     ${messageArguments.join(', ')});
}
""", isShared: canBeShared);
}
