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

import 'package:expect/async_helper.dart' show asyncTest;
import 'package:front_end/src/api_prototype/compiler_options.dart'
    show CompilerOptions;
import 'package:front_end/src/api_prototype/kernel_generator.dart'
    show kernelForModule;
import 'package:front_end/src/api_prototype/memory_file_system.dart'
    show MemoryFileSystem;
import 'package:front_end/src/base/compiler_context.dart' show CompilerContext;
import 'package:front_end/src/base/processed_options.dart'
    show ProcessedOptions;
import 'package:front_end/src/compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation;
import 'package:front_end/src/kernel/utils.dart' show serializeComponent;
import 'package:front_end/src/kernel/cfe_verifier.dart' show verifyComponent;
import 'package:kernel/ast.dart' show Component;
import 'package:kernel/target/targets.dart';
import 'package:kernel/verifier.dart' show VerificationStage;

const Map<String, String> files = const <String, String>{
  "repro.dart": """

import 'lib.dart';

abstract class M<M_K, M_V> implements Map<M_K, Set<M_V>> {}

abstract class C<C_K, C_V> extends UnmodifiableMapView<C_K, Set<C_V>>
    with M<C_K, C_V> {
  C._() : super(null);
}
""",
  "lib.dart": """abstract class MapView<K, V> {
  const MapView(Map<K, V> map);
}

abstract class _UnmodifiableMapMixin<K, V> {}

abstract class UnmodifiableMapView<K, V> extends MapView<K, V>
    with _UnmodifiableMapMixin<K, V> {
  UnmodifiableMapView(Map<K, V> map) : super(map);
}""",
};

Future<void> test() async {
  final String platformBaseName = "vm_platform_strong.dill";
  final Uri base = Uri.parse("org-dartlang-test:///");
  final Uri platformDill = base.resolve(platformBaseName);
  final List<int> platformDillBytes = await new File.fromUri(
          computePlatformBinariesLocation(forceBuildDir: true)
              .resolve(platformBaseName))
      .readAsBytes();
  MemoryFileSystem fs = new MemoryFileSystem(base);
  fs.entityForUri(platformDill).writeAsBytesSync(platformDillBytes);
  fs
      .entityForUri(base.resolve("lib.dart"))
      .writeAsStringSync(files["lib.dart"]!);
  CompilerOptions options = new CompilerOptions()
    ..fileSystem = fs
    ..sdkSummary = platformDill;

  Component component =
      (await kernelForModule(<Uri>[base.resolve("lib.dart")], options))
          .component!;

  fs = new MemoryFileSystem(base);
  fs.entityForUri(platformDill).writeAsBytesSync(platformDillBytes);
  fs
      .entityForUri(base.resolve("lib.dart.dill"))
      .writeAsBytesSync(serializeComponent(component));
  fs
      .entityForUri(base.resolve("repro.dart"))
      .writeAsStringSync(files["repro.dart"]!);

  options = new CompilerOptions()
    ..fileSystem = fs
    ..additionalDills = <Uri>[base.resolve("lib.dart.dill")]
    ..sdkSummary = platformDill
    ..target = new NoneTarget(new TargetFlags());

  List<Uri> inputs = <Uri>[base.resolve("repro.dart")];

  component = (await kernelForModule(inputs, options)).component!;

  List<Object> errors = await CompilerContext.runWithOptions(
      new ProcessedOptions(options: options, inputs: inputs),
      (CompilerContext c) => new Future<List<Object>>.value(verifyComponent(
          c, VerificationStage.afterModularTransformations, component,
          skipPlatform: true)));

  serializeComponent(component);

  if (errors.isNotEmpty) {
    throw "Verification failed";
  }
}

void main() {
  asyncTest(test);
}
