// 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/kernel_front_end.dart' show createLoadedLibrariesSet;
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,
    ),
  );
  final result = await compileTestCaseToKernelProgram(source, target: target);

  final mainLibrary = result.component.mainMethod!.enclosingLibrary;

  final sink = ByteSink();
  final coreTypes = result.coreTypes ?? CoreTypes(result.component);
  final hierarchy =
      result.classHierarchy ?? ClassHierarchy(result.component, coreTypes);
  generateBytecode(
    result.component,
    sink,
    options: BytecodeOptions(),
    libraries: [mainLibrary],
    extraLoadedLibraries: result.loadedLibraries,
    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);
}

// Similar to CompilerResult from pkg/vm/bin/kernel_service.dart.
class CompilerResult {
  final Component component;
  final Set<Library> loadedLibraries;
  final ClassHierarchy? classHierarchy;
  final CoreTypes? coreTypes;

  CompilerResult(
    this.component,
    this.loadedLibraries,
    this.classHierarchy,
    this.coreTypes,
  );
}

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

  final result = (await kernelForProgram(sourceUri, options))!;
  final Component component = result.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 CompilerResult(
    component,
    // Use the same calculation as SingleShotCompilerWrapper.
    createLoadedLibrariesSet(
      result.loadedComponents,
      result.sdkComponent,
      includePlatform: false,
    ),
    result.classHierarchy,
    result.coreTypes,
  );
}

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),
        );
      }
    }
  });
}
