// 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' show File, Platform;

import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;

import 'package:front_end/src/api_prototype/compiler_options.dart'
    show DiagnosticMessage;

import 'package:kernel/kernel.dart'
    show Class, Component, ConstantExpression, Field, IntConstant, Library;

import 'package:kernel/target/targets.dart' show NoneTarget, TargetFlags;

import 'binary_md_dill_reader.dart' show BinaryMdDillReader;

import 'incremental_suite.dart' show getOptions, normalCompileToComponent;

import 'utils/io_utils.dart' show computeRepoDir;

const String maxSupported =
    "static const uint32_t kMaxSupportedKernelFormatVersion = ";

// Match stuff like "V(Nothing, 0)"
final RegExp tagParser = new RegExp(r"V\((\w*),\s*(\d+)\)");

// Match stuff like "kNullConstant = 0,"
final RegExp constantTagParser = new RegExp(r"k(\w*)\s*=\s*(\d+)");

Future<void> main() async {
  File binaryMd = new File("$repoDir/pkg/kernel/binary.md");
  String binaryMdContent = binaryMd.readAsStringSync();

  BinaryMdDillReader binaryMdReader =
      new BinaryMdDillReader(binaryMdContent, []);
  binaryMdReader.setup();

  File vmTagFile = new File("$repoDir/runtime/vm/kernel_binary.h");
  String vmTagContent = vmTagFile.readAsStringSync();
  List<String> vmTagLines = vmTagContent.split("\n");
  int? vmVersion;
  Map<int, String> vmTagToName = {};
  Map<int, String> vmConstantTagToName = {};
  for (int i = 0; i < vmTagLines.length; i++) {
    String line = vmTagLines[i];
    if (line.startsWith(maxSupported)) {
      vmVersion = int.parse(line
          .substring(line.indexOf(maxSupported) + maxSupported.length)
          .substring(0, 2) // Assume version < 100 for now.
          .trim());
    } else if (line.startsWith("#define KERNEL_TAG_LIST(V)")) {
      while (true) {
        RegExpMatch? match = tagParser.firstMatch(line);
        if (match != null) {
          int value = int.parse(match.group(2)!);
          int end = value + 1;
          if (uses8Tags(match.group(1)!)) {
            end = value + 8;
          }
          for (int j = value; j < end; j++) {
            vmTagToName[j] = match.group(1)!;
          }
        }
        if (!vmTagLines[i].trim().endsWith(r"\")) {
          break;
        }
        i++;
        line = vmTagLines[i];
      }
    } else if (line.startsWith("enum ConstantTag {")) {
      while (true) {
        RegExpMatch? match = constantTagParser.firstMatch(line);
        if (match != null) {
          vmConstantTagToName[int.parse(match.group(2)!)] = match.group(1)!;
        }
        if (vmTagLines[i].trim().startsWith("}")) {
          break;
        }
        i++;
        line = vmTagLines[i];
      }
    }
  }

  final Uri kernelTagUri = Uri.base.resolve("pkg/kernel/lib/binary/tag.dart");
  Component c = await normalCompileToComponent(kernelTagUri,
      options: getOptions()
        ..target = new NoneTarget(new TargetFlags())
        ..onDiagnostic = (DiagnosticMessage message) {
          if (message.severity == Severity.error) {
            print(message.plainTextFormatted.join('\n'));
          }
        });

  Library tagLibrary =
      c.libraries.firstWhere((l) => l.fileUri.pathSegments.last == "tag.dart");
  Class tagClass = tagLibrary.classes.firstWhere((c) => c.name == "Tag");
  Class constantTagClass =
      tagLibrary.classes.firstWhere((c) => c.name == "ConstantTag");

  int? tagVersion;
  for (TagCompare compareMe in [
    new TagCompare(binaryMdReader.tagToName, binaryMdReader.version,
        vmTagToName, vmVersion, tagClass),
    new TagCompare(binaryMdReader.constantTagToName, binaryMdReader.version,
        vmConstantTagToName, vmVersion, constantTagClass)
  ]) {
    Map<int, String> tagToName = {};
    for (Field f in compareMe.tagClass.fields) {
      // Class doesn't only contain tag stuff.
      if (f.name.text.endsWith("Mask")) continue;
      if (f.name.text.endsWith("HighBit")) continue;
      if (f.name.text.endsWith("Bias")) continue;
      if (f.name.text == "ComponentFile") continue;
      ConstantExpression value = f.initializer as ConstantExpression;
      IntConstant intConstant = value.constant as IntConstant;
      int intValue = intConstant.value;
      if (f.name.text == "BinaryFormatVersion") {
        tagVersion = intValue;
        continue;
      }

      int end = intValue + 1;
      // There are a few special cases that takes up a total of 8 tags.
      if (uses8Tags(f.name.text)) {
        end = intValue + 8;
      }
      for (; intValue < end; intValue++) {
        if (tagToName[intValue] != null) {
          throw "Double entry for ${intValue}: "
              "${f.name.text} and ${tagToName[intValue]}";
        }
        tagToName[intValue] = f.name.text;
      }
    }

    Map<int, String> tagToNameMd = {};
    for (MapEntry<int, String> entry in compareMe.mdTagToName.entries) {
      if (entry.value.contains("<")) {
        tagToNameMd[entry.key] =
            entry.value.substring(0, entry.value.indexOf("<")).trim();
      } else {
        tagToNameMd[entry.key] = entry.value;
      }
    }

    // Kernels tag.dart vs binary.mds tags.
    for (int key in tagToNameMd.keys) {
      String nameMd = tagToNameMd[key]!;
      String name = tagToName[key]!;
      if (nameMd == name) continue;
      throw "$key: $nameMd vs $name";
    }
    for (int key in tagToName.keys) {
      String nameMd = tagToNameMd[key]!;
      String name = tagToName[key]!;
      if (nameMd == name) continue;
      throw "$key: $nameMd vs $name";
    }
    if (tagVersion != compareMe.mdVersion) {
      throw "Version in tag.dart: $tagVersion; "
          "version in binary.md: ${compareMe.mdVersion}";
    }

    // Kernels tag.dart vs the VMs tags.
    // Here we only compare one way because the VM can have more (old) tags.
    for (int key in tagToName.keys) {
      String nameVm = compareMe.vmTagToName[key]!;
      String name = tagToName[key]!;
      if (nameVm == name) continue;
      throw "$key: $nameVm vs $name";
    }
    if (tagVersion != compareMe.vmVersion) {
      throw "Version in tag.dart: $tagVersion; "
          "version in VM: ${compareMe.vmVersion}";
    }
  }

  print("OK");
}

bool uses8Tags(String name) {
  return name == "SpecializedVariableGet" ||
      name == "SpecializedVariableSet" ||
      name == "SpecializedIntLiteral";
}

final String repoDir = computeRepoDir();

String get dartVm => Platform.executable;

class TagCompare {
  final Map<int, String> mdTagToName;
  final int? mdVersion;
  final Map<int, String> vmTagToName;
  final int? vmVersion;
  final Class tagClass;

  TagCompare(this.mdTagToName, this.mdVersion, this.vmTagToName, this.vmVersion,
      this.tagClass);
}
