// Copyright (c) 2023, 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:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';

import 'package:kernel/kernel.dart';
import 'package:test/test.dart';

// Reuse some test infrastructure.
import 'frontend_server_test.dart';

void main() async {
  group('full compiler tests', () {
    final Uri platformKernel =
        computePlatformBinariesLocation().resolve('vm_platform.dill');
    final Uri sdkRoot = computePlatformBinariesLocation();

    late Directory tempDir;
    late File mainFile;
    late File packageConfigFile;
    late File nativeAssetsYamlFile;
    late File dillFile;

    setUp(() async {
      tempDir = await Directory.systemTemp.createTemp('frontendServerTest');

      mainFile = new File('${tempDir.path}/a.dart');
      await mainFile.create(recursive: true);
      await mainFile.writeAsString('''
void main() {
  print(42);
}
''');

      packageConfigFile =
          new File('${tempDir.path}/.dart_tool/package_config.json');
      await packageConfigFile.create(recursive: true);
      await packageConfigFile.writeAsString(jsonEncode({
        "configVersion": 2,
        "packages": [],
      }));

      nativeAssetsYamlFile =
          new File('${tempDir.path}/.dart_tool/native_assets.yaml');
      await nativeAssetsYamlFile.create(recursive: true);
      await nativeAssetsYamlFile.writeAsString(jsonEncode({
        'format-version': [1, 0, 0],
        'native-assets': {
          new Abi.current().toString(): {
            mainFile.uri.toString(): ['executable'],
          },
        },
      }));

      // Other setup.
      dillFile = new File('${tempDir.path}/app.dill');
    });

    tearDown(() async {
      return await tempDir.delete(recursive: true);
    });

    group('--incremental', () {
      Future<void> testPassInNativeAssetsAtStartup({
        List<String> additionalStartupArguments = const [],
      }) async {
        final FrontendServer frontendServer = new FrontendServer();
        Future<int> result = frontendServer.open(<String>[
          '--sdk-root=${sdkRoot.toFilePath()}',
          '--incremental',
          '--platform=${platformKernel.path}',
          '--output-dill=${dillFile.path}',
          '--native-assets=${nativeAssetsYamlFile.path}',
        ]);

        frontendServer.compile(mainFile.path);

        int count = 0;
        frontendServer.listen((Result compiledResult) async {
          CompilationResult result =
              new CompilationResult.parse(compiledResult.status);
          switch (count) {
            case 0:
              expect(await dillFile.exists(), equals(true));
              expect(result.filename, dillFile.path);
              expect(result.errorsCount, 0);
              count += 1;
              frontendServer.accept();
              frontendServer.reset();

              final Component component =
                  loadComponentFromBinary(dillFile.path);
              final Library? nativeAssetsLibrary =
                  _findNativeAssetsLibrary(component);
              expect(nativeAssetsLibrary, isNotNull);

              final Library firstLib = component.libraries.first;
              expect(firstLib.importUri != _nativeAssetsLibraryUri, true);
              expect(nativeAssetsLibrary!.nonNullable, firstLib.nonNullable);

              await mainFile.writeAsString('''
void main() {
  print(1337);
}
''');

              frontendServer.recompile(mainFile.uri);
              break;
            case 1:
              expect(await dillFile.exists(), equals(true));
              expect(result.filename, dillFile.path);
              expect(result.errorsCount, 0);
              frontendServer.accept();
              frontendServer.quit();

              final Component component =
                  loadComponentFromBinary(dillFile.path);
              final Library? nativeAssetsLibrary =
                  _findNativeAssetsLibrary(component);
              expect(nativeAssetsLibrary, isNotNull);

              break;
          }
        });
        expect(await result, 0);
        frontendServer.close();
      }

      test('pass in native assets at startup', () async {
        await testPassInNativeAssetsAtStartup();
      });

      test('--no-sound-null-safety', () async {
        await testPassInNativeAssetsAtStartup(additionalStartupArguments: [
          '--no-sound-null-safety',
        ]);
      });

      test('--incremental-serialization', () async {
        await testPassInNativeAssetsAtStartup(additionalStartupArguments: [
          '--incremental-serialization',
        ]);
      });

      test('set native assets later', () async {
        final FrontendServer frontendServer = new FrontendServer();
        Future<int> result = frontendServer.open(<String>[
          '--sdk-root=${sdkRoot.toFilePath()}',
          '--incremental',
          '--platform=${platformKernel.path}',
          '--output-dill=${dillFile.path}',
        ]);

        frontendServer.compile(mainFile.path);

        int count = 0;
        frontendServer.listen((Result compiledResult) async {
          CompilationResult result =
              new CompilationResult.parse(compiledResult.status);
          switch (count) {
            case 0:
              expect(await dillFile.exists(), equals(true));
              expect(result.filename, dillFile.path);
              expect(result.errorsCount, 0);
              count += 1;
              frontendServer.accept();
              frontendServer.reset();

              final Component component =
                  loadComponentFromBinary(dillFile.path);
              final Library? nativeAssetsLibrary =
                  _findNativeAssetsLibrary(component);
              expect(nativeAssetsLibrary, isNull);

              frontendServer.setNativeAssets(uri: nativeAssetsYamlFile.uri);
              frontendServer.recompile(mainFile.uri);
              break;
            case 1:
              expect(await dillFile.exists(), equals(true));
              expect(result.filename, dillFile.path);
              expect(result.errorsCount, 0);
              count += 1;
              frontendServer.accept();

              final Component component =
                  loadComponentFromBinary(dillFile.path);
              final Library? nativeAssetsLibrary =
                  _findNativeAssetsLibrary(component);
              expect(nativeAssetsLibrary, isNotNull);

              frontendServer.compileNativeAssetsOnly();
              break;
            case 2:
              expect(await dillFile.exists(), equals(true));
              expect(result.filename, dillFile.path);
              expect(result.errorsCount, 0);
              count += 1;

              final Component component =
                  loadComponentFromBinary(dillFile.path);
              final Library? nativeAssetsLibrary =
                  _findNativeAssetsLibrary(component);
              expect(nativeAssetsLibrary, isNotNull);

              frontendServer.quit();
          }
        });
        expect(await result, 0);
        frontendServer.close();
      });

      Future<void> testInitializeFromDill({
        bool passNativeAssetsOnFirstStartup = false,
        bool passNativeAssetsOnSecondStartup = false,
      }) async {
        {
          final FrontendServer frontendServer = new FrontendServer();
          Future<int> frontendServerResult = frontendServer.open(<String>[
            '--sdk-root=${sdkRoot.toFilePath()}',
            '--incremental',
            '--platform=${platformKernel.path}',
            '--output-dill=${dillFile.path}',
            if (passNativeAssetsOnFirstStartup)
              '--native-assets=${nativeAssetsYamlFile.path}',
          ]);

          frontendServer.compile(mainFile.path);

          final Result compiledResult =
              await frontendServer.receivedResults.stream.first;
          CompilationResult result =
              new CompilationResult.parse(compiledResult.status);
          expect(await dillFile.exists(), equals(true));
          expect(result.filename, dillFile.path);
          expect(result.errorsCount, 0);

          frontendServer.accept();
          frontendServer.quit();

          final Component component = loadComponentFromBinary(dillFile.path);
          final Library? nativeAssetsLibrary =
              _findNativeAssetsLibrary(component);
          expect(nativeAssetsLibrary,
              passNativeAssetsOnFirstStartup ? isNotNull : isNull);

          expect(await frontendServerResult, 0);
          frontendServer.close();
        }

        {
          final FrontendServer frontendServer = new FrontendServer();
          Future<int> frontendServerResult = frontendServer.open(<String>[
            '--sdk-root=${sdkRoot.toFilePath()}',
            '--incremental',
            '--platform=${platformKernel.path}',
            '--output-dill=${dillFile.path}',
            '--initialize-from-dill=${dillFile.path}',
            if (passNativeAssetsOnSecondStartup)
              '--native-assets=${nativeAssetsYamlFile.path}',
          ]);

          frontendServer.compile(mainFile.path);

          final Result compiledResult =
              await frontendServer.receivedResults.stream.first;
          CompilationResult result =
              new CompilationResult.parse(compiledResult.status);
          expect(await dillFile.exists(), equals(true));
          expect(result.filename, dillFile.path);
          expect(result.errorsCount, 0);

          frontendServer.accept();
          frontendServer.quit();

          final Component component = loadComponentFromBinary(dillFile.path);
          final Library? nativeAssetsLibrary =
              _findNativeAssetsLibrary(component);
          expect(nativeAssetsLibrary,
              passNativeAssetsOnSecondStartup ? isNotNull : isNull);

          expect(await frontendServerResult, 0);
          frontendServer.close();
        }
      }

      test('--initialize-from-dill embed native-assets', () async {
        // This should forget the native assets, the incremental compiler
        // should be seen as an optimization, _not_ as a thing that keeps
        // state intentionally.
        await testInitializeFromDill(passNativeAssetsOnFirstStartup: true);
      });

      test('--initialize-from-dill second start with --native-assets',
          () async {
        await testInitializeFromDill(passNativeAssetsOnSecondStartup: true);
      });

      test('--initialize-from-dill replace --native-assets', () async {
        // This should forget the native assets from the first invocation.
        await testInitializeFromDill(
          passNativeAssetsOnFirstStartup: true,
          passNativeAssetsOnSecondStartup: true,
        );
      });
    });

    group('--aot --tfa', () {
      test('pass in native assets at startup', () async {
        final FrontendServer frontendServer = new FrontendServer();
        Future<int> frontendServerResult = frontendServer.open(<String>[
          '--sdk-root=${sdkRoot.toFilePath()}',
          '--platform=${platformKernel.path}',
          '--aot',
          '--tfa',
          '--output-dill=${dillFile.path}',
          '--native-assets=${nativeAssetsYamlFile.path}',
          mainFile.path
        ]);

        expect(await frontendServerResult, 0);
        frontendServer.close();

        expect(await dillFile.exists(), equals(true));
        final Component component = loadComponentFromBinary(dillFile.path);
        final Library? nativeAssetsLibrary =
            _findNativeAssetsLibrary(component);
        expect(nativeAssetsLibrary, isNotNull);
      });

      test('pass in native assets only at startup', () async {
        final FrontendServer frontendServer = new FrontendServer();
        Future<int> frontendServerResult = frontendServer.open(<String>[
          '--sdk-root=${sdkRoot.toFilePath()}',
          '--platform=${platformKernel.path}',
          '--aot',
          '--tfa',
          '--output-dill=${dillFile.path}',
          '--native-assets=${nativeAssetsYamlFile.path}',
          '--native-assets-only',
        ]);

        expect(await frontendServerResult, 0);
        frontendServer.close();

        expect(await dillFile.exists(), equals(true));
        final Component component = loadComponentFromBinary(dillFile.path);
        final Library? nativeAssetsLibrary =
            _findNativeAssetsLibrary(component);
        expect(nativeAssetsLibrary, isNotNull);
      });
    });
  });
}

final Uri _nativeAssetsLibraryUri = Uri.parse('vm:ffi:native-assets');

Library? _findNativeAssetsLibrary(Component component) {
  for (final Library library in component.libraries) {
    if (library.importUri == _nativeAssetsLibraryUri) {
      return library;
    }
  }
  return null;
}
