// 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.

// @dart=2.9

import 'dart:io';

import 'package:kernel/target/targets.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/binary/ast_to_binary.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/src/printer.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import 'package:vm/kernel_front_end.dart'
    show runGlobalTransformations, ErrorDetector;
import 'package:vm/transformations/type_flow/transformer.dart' as globalTypeFlow
    show transformComponent;

import '../../common_test_utils.dart';

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

runTestCase(Uri source) async {
  await shakeAndRun(source);
  await compileAOT(source);
}

Future<void> shakeAndRun(Uri source) async {
  final target = TestingVmTarget(TargetFlags());
  Component component =
      await compileTestCaseToKernelProgram(source, target: target);

  List<Class> messageClasses = component.libraries
      .expand(
        (lib) => lib.classes.where((klass) =>
            klass.superclass != null &&
            klass.superclass.name == "GeneratedMessage"),
      )
      .toList();

  globalTypeFlow.transformComponent(
      TestingVmTarget(TargetFlags()), CoreTypes(component), component,
      treeShakeProtobufs: true, treeShakeSignatures: false);

  for (Class messageClass in messageClasses) {
    expect(messageClass.enclosingLibrary.classes.contains(messageClass),
        messageClass.name.endsWith('Keep'),
        reason: '${messageClass.toText(astTextStrategyForTesting)}');
  }

  final systemTempDir = Directory.systemTemp;
  final file = File('${systemTempDir.path}/${source.pathSegments.last}.dill');
  try {
    final sink = file.openWrite();
    final printer = BinaryPrinter(sink, includeSources: false);

    component.metadata.clear();
    printer.writeComponentFile(component);
    await sink.close();

    final result = Process.runSync(
        Platform.resolvedExecutable, ['--enable-asserts', file.path]);
    expect(result.exitCode, 0, reason: '${result.stderr}\n${result.stdout}');
  } finally {
    if (file.existsSync()) {
      file.deleteSync();
    }
  }
}

Future<void> compileAOT(Uri source) async {
  final target = TestingVmTarget(TargetFlags());
  Component component =
      await compileTestCaseToKernelProgram(source, target: target);

  // Imitate the global transformations as run by the protobuf-aware tree shaker
  // in AOT mode.
  // Copied verbatim from pkg/vm/bin/protobuf_aware_treeshaker.dart.
  const bool useGlobalTypeFlowAnalysis = true;
  const bool enableAsserts = false;
  const bool useProtobufAwareTreeShakerV2 = true;
  final nopErrorDetector = ErrorDetector();
  runGlobalTransformations(
    target,
    component,
    useGlobalTypeFlowAnalysis,
    enableAsserts,
    useProtobufAwareTreeShakerV2,
    nopErrorDetector,
  );
}

main() async {
  final testCases = Directory(path.join(
    pkgVmDir,
    'testcases',
    'transformations',
    'type_flow',
    'transformer',
    'protobuf_handler',
    'lib',
  )).listSync().where((f) => f.path.endsWith('_test.dart'));
  for (final entry in testCases) {
    test(entry.path, () => runTestCase(entry.uri));
  }
}
