// 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, {bool isClosureContextLoweringEnabled = false}) async {
  final target = VmTarget(TargetFlags(
      isClosureContextLoweringEnabled: isClosureContextLoweringEnabled));
  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));
      }
    }
  });

  group('gen-bytecode-with-closure-context-lowering', () {
    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, isClosureContextLoweringEnabled: true));
      }
    }
  });
}
