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

import '../helpers/memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/elements/entities.dart'
    show LibraryEntity, ClassEntity;
import 'package:compiler/src/kernel/dart2js_target.dart';
import 'package:compiler/src/phase/load_kernel.dart' as load_kernel;
import 'package:expect/expect.dart';
import 'package:front_end/src/api_prototype/front_end.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/api_prototype/standard_file_system.dart';
import 'package:front_end/src/api_unstable/dart2js.dart';
import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
import 'package:kernel/ast.dart';
import 'package:kernel/target/targets.dart' show TargetFlags;

/// Test that the compiler can load kernel in modular fragments.
main() {
  asyncTest(() async {
    var aDill = await compileUnit(['a0.dart'], {'a0.dart': sourceA});
    var bDill = await compileUnit(
        ['b1.dart'], {'b1.dart': sourceB, 'a.dill': aDill},
        deps: ['a.dill']);
    var cDill = await compileUnit(
        ['c2.dart'], {'c2.dart': sourceC, 'a.dill': aDill, 'b.dill': bDill},
        deps: ['a.dill', 'b.dill']);

    DiagnosticCollector diagnostics = DiagnosticCollector();
    OutputCollector output = OutputCollector();
    Uri entryPoint = Uri.parse('org-dartlang-test:///c2.dart');
    var compiler = compilerFor(
        entryPoint: entryPoint,
        options: [
          '--input-dill=memory:c.dill',
          '--dill-dependencies=memory:a.dill,memory:b.dill'
        ],
        memorySourceFiles: {'a.dill': aDill, 'b.dill': bDill, 'c.dill': cDill},
        diagnosticHandler: diagnostics,
        outputProvider: output);
    load_kernel.Output result = await load_kernel.run(load_kernel.Input(
        compiler.options,
        compiler.provider,
        compiler.reporter,
        compiler.initializedCompilerState,
        false));
    compiler.frontendStrategy
        .registerLoadedLibraries(result.component, result.libraries);

    Expect.equals(0, diagnostics.errors.length);
    Expect.equals(0, diagnostics.warnings.length);

    ElementEnvironment environment =
        compiler.frontendStrategy.elementEnvironment;
    LibraryEntity library = environment.lookupLibrary(toTestUri('b1.dart'));
    Expect.isNotNull(library);
    ClassEntity clss = environment.lookupClass(library, 'B1');
    Expect.isNotNull(clss);
    var member = environment.lookupClassMember(clss, 'foo');
    Expect.isNotNull(member);
  });
}

/// Generate a component for a modular complation unit.
Future<List<int>> compileUnit(List<String> inputs, Map<String, dynamic> sources,
    {List<String> deps: const []}) async {
  var fs = MemoryFileSystem(_defaultDir);
  sources.forEach((name, data) {
    var entity = fs.entityForUri(toTestUri(name));
    if (data is String) {
      entity.writeAsStringSync(data);
    } else {
      entity.writeAsBytesSync(data);
    }
  });
  List<Uri> additionalDills = [
    computePlatformBinariesLocation().resolve("dart2js_platform.dill"),
  ]..addAll(deps.map(toTestUri));
  fs.entityForUri(toTestUri('.packages')).writeAsStringSync('');
  var options = CompilerOptions()
    ..target = Dart2jsTarget("dart2js", TargetFlags(enableNullSafety: true))
    ..fileSystem = TestFileSystem(fs)
    ..nnbdMode = NnbdMode.Strong
    ..additionalDills = additionalDills
    ..packagesFileUri = toTestUri('.packages')
    ..explicitExperimentalFlags = {ExperimentalFlag.nonNullable: true};
  var inputUris = inputs.map(toTestUri).toList();
  var inputUriSet = inputUris.toSet();
  var component = (await kernelForModule(inputUris, options)).component;
  for (var lib in component.libraries) {
    if (!inputUriSet.contains(lib.importUri)) {
      component.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
      lib.computeCanonicalNames();
    }
  }
  return serializeComponent(component,
      filter: (Library lib) => inputUriSet.contains(lib.importUri));
}

Uri _defaultDir = Uri.parse('org-dartlang-test:///');

Uri toTestUri(String relativePath) => _defaultDir.resolve(relativePath);

class TestFileSystem implements FileSystem {
  final MemoryFileSystem memory;
  final FileSystem physical = StandardFileSystem.instance;

  TestFileSystem(this.memory);

  @override
  FileSystemEntity entityForUri(Uri uri) {
    if (uri.isScheme('file')) return physical.entityForUri(uri);
    return memory.entityForUri(uri);
  }
}

const sourceA = '''
class A0 {
  StringBuffer buffer = StringBuffer();
}
''';

const sourceB = '''
import 'a0.dart';

class B1 extends A0 {
  A0? get foo => null;
}

A0 createA0() => A0();
''';

const sourceC = '''
import 'b1.dart';

class C2 extends B1 {
  final foo = createA0();
}

main() => print(C2().foo.buffer.toString());
''';
