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

/// Test to ensure that desugaring APIs used by clients like dart2js are
/// always up to date.
///
/// Desugaring APIs are methods that inspect the kernel output to find
/// structures that are assumed to always be generated by the CFE. If the CFE
/// changes its invariants, the desugaring APIs will change together to hide
/// these changes from clients.

import 'dart:io';

import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:front_end/src/api_unstable/dart2js.dart' as api;
import 'package:front_end/src/compute_platform_binaries_location.dart';
import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
import 'package:front_end/src/testing/compiler_common.dart';
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;

Future<void> main() async {
  await asyncTest(() async {
    await testRedirectingFactoryDirect();
    await testRedirectingFactorySerialized();
    await testRedirectingFactoryPatchFile();
  });
}

Future<void> testRedirectingFactoryDirect() async {
  var component = await compileUnit(['a.dart'], {'a.dart': aSource});
  checkIsRedirectingFactory(component!, 'a.dart', 'A', 'foo');
  checkIsRedirectingFactory(component, 'core', 'Uri', 'file');
}

Future<void> testRedirectingFactorySerialized() async {
  var component = await compileUnit(['a.dart'], {'a.dart': aSource});
  var bytes = serializeComponent(component!);
  component = new ir.Component();
  new BinaryBuilder(bytes).readComponent(component);
  checkIsRedirectingFactory(component, 'a.dart', 'A', 'foo');
  checkIsRedirectingFactory(component, 'core', 'Uri', 'file');
}

// regression test: redirecting factories from patch files don't have the
// redirecting-factory flag stored in kernel.
Future<void> testRedirectingFactoryPatchFile() async {
  var componentUri =
      computePlatformBinariesLocation().resolve('dart2js_platform.dill');
  var component = new ir.Component();
  new BinaryBuilder(new File.fromUri(componentUri).readAsBytesSync())
      .readComponent(component);
  checkIsRedirectingFactory(component, 'collection', 'HashMap', 'identity');
}

void checkIsRedirectingFactory(ir.Component component, String uriPath,
    String className, String constructorName) {
  var lib =
      component.libraries.firstWhere((l) => l.importUri.path.endsWith(uriPath));
  var cls = lib.classes.firstWhere((c) => c.name == className);
  ir.Procedure member = cls.members
      .firstWhere((m) => m.name.text == constructorName) as ir.Procedure;
  Expect.isTrue(
      member.kind == ir.ProcedureKind.Factory, "$member is not a factory");
  Expect.isTrue(api.isRedirectingFactory(member));
  Expect.isTrue(member.isRedirectingFactory);
}

const aSource = '''
class A {
  factory A.foo(int x) = _B;
}

class _B implements A {
  _B(int x);
}
''';
