// Copyright (c) 2024, 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' show BytesBuilder;

import 'package:dart2bytecode/bytecode_generator.dart' show generateBytecode;
import 'package:dart2bytecode/bytecode_serialization.dart'
    show LinkReader, BufferedReader;
import 'package:dart2bytecode/declarations.dart' as bytecode_declarations
    show Component;
import 'package:dart2bytecode/options.dart' show BytecodeOptions;
import 'package:front_end/src/api_unstable/vm.dart'
    show
        CompilerOptions,
        computePlatformBinariesLocation,
        CfeDiagnosticMessage,
        kernelForProgram;
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:test/test.dart';
import 'package:vm/modular/target/vm.dart';

/// Environment define to update expectation files on failures.
const kUpdateExpectations = 'updateExpectations';

final String dartSdkPkgDir = Platform.script.resolve('../..').toFilePath();

runTestCase(Uri source) async {
  final target = VmTarget(TargetFlags());
  Component component =
      await compileTestCaseToKernelProgram(source, target: target);

  final mainLibrary = component.mainMethod!.enclosingLibrary;
  final coreTypes = CoreTypes(component);
  final hierarchy = ClassHierarchy(component, coreTypes);

  final sink = ByteSink();
  generateBytecode(component, sink,
      options: BytecodeOptions(),
      libraries: [mainLibrary],
      coreTypes: coreTypes,
      hierarchy: hierarchy,
      target: target);

  final reader = BufferedReader(LinkReader(), sink.builder.takeBytes());
  String actual = bytecode_declarations.Component.read(reader).toString();

  // Remove absolute library URIs.
  actual = actual.replaceAll(
      new Uri.file(dartSdkPkgDir).toString(), 'DART_SDK/pkg/');

  compareResultWithExpectationsFile(source, actual);
}

Future<Component> compileTestCaseToKernelProgram(Uri sourceUri,
    {required Target target}) async {
  final platformKernel =
      computePlatformBinariesLocation().resolve('vm_platform.dill');
  final options = CompilerOptions()
    ..target = target
    ..additionalDills = <Uri>[platformKernel]
    ..environmentDefines = {}
    ..onDiagnostic = (CfeDiagnosticMessage message) {
      fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
    };

  final Component component =
      (await kernelForProgram(sourceUri, options))!.component!;

  // Make sure the library name is the same and does not depend on the order
  // of test cases.
  component.mainMethod!.enclosingLibrary.name = '#lib';
  return component;
}

class ByteSink implements Sink<List<int>> {
  final BytesBuilder builder = BytesBuilder();

  @override
  void add(List<int> data) {
    builder.add(data);
  }

  @override
  void close() {}
}

class Difference {
  final int line;
  final String actual;
  final String expected;

  Difference(this.line, this.actual, this.expected);
}

Difference findFirstDifference(String actual, String expected) {
  final actualLines = actual.split('\n');
  final expectedLines = expected.split('\n');
  int i = 0;
  for (; i < actualLines.length && i < expectedLines.length; ++i) {
    if (actualLines[i] != expectedLines[i]) {
      return Difference(i + 1, actualLines[i], expectedLines[i]);
    }
  }
  return Difference(i + 1, i < actualLines.length ? actualLines[i] : '<END>',
      i < expectedLines.length ? expectedLines[i] : '<END>');
}

void compareResultWithExpectationsFile(
  Uri source,
  String actual, {
  String expectFilePostfix = '',
}) {
  final baseFilename = '${source.toFilePath()}$expectFilePostfix';
  final expectFile = new File('$baseFilename.expect');
  final expected = expectFile.existsSync() ? expectFile.readAsStringSync() : '';

  if (actual != expected) {
    if (bool.fromEnvironment(kUpdateExpectations)) {
      expectFile.writeAsStringSync(actual);
      print("  Updated $expectFile");
    } else {
      Difference diff = findFirstDifference(actual, expected);
      fail("""

Result is different for the test case $source

The first difference is at line ${diff.line}.
Actual:   ${diff.actual}
Expected: ${diff.expected}

This failure can be caused by changes in the front-end if it starts generating
different kernel AST for the same Dart programs.

In order to re-generate expectations run tests with -D$kUpdateExpectations=true VM option:

  tools/test.py -m release --vm-options -D$kUpdateExpectations=true pkg/dart2bytecode/

""");
    }
  }
}

main() {
  group('gen-bytecode', () {
    final testCasesDir =
        new Directory(dartSdkPkgDir + 'dart2bytecode/testcases');

    for (var entry
        in testCasesDir.listSync(recursive: true, followLinks: false)) {
      if (entry.path.endsWith(".dart")) {
        test(entry.path, () => runTestCase(entry.uri));
      }
    }
  });
}
