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

import 'dart:io';
import 'package:_fe_analyzer_shared/src/testing/features.dart';
import 'package:expect/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/enqueue.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:compiler/src/universe/member_usage.dart';
import 'package:compiler/src/universe/resolution_world_builder.dart';
import 'package:compiler/src/util/enumset.dart';
import 'package:kernel/ast.dart' as ir;
import '../equivalence/id_equivalence.dart';
import '../equivalence/id_equivalence_helper.dart';

main(List<String> args) {
  asyncTest(() async {
    Directory dataDir = Directory.fromUri(Platform.script.resolve('data'));
    print('------------------------------------------------------------------');
    print(' Test with enqueuer checks');
    print('------------------------------------------------------------------');
    await checkTests(
      dataDir,
      const ClosedWorldDataComputer(false),
      args: args,
      testedConfigs: allSpecConfigs,
    );
    print('------------------------------------------------------------------');
    print(' Test without enqueuer checks');
    print('------------------------------------------------------------------');
    await checkTests(
      dataDir,
      const ClosedWorldDataComputer(true),
      args: args,
      testedConfigs: allSpecConfigs,
    );
  });
}

class Tags {
  static const String init = 'init';
  static const String read = 'read';
  static const String write = 'write';
  static const String invoke = 'invoke';
}

class ClosedWorldDataComputer extends DataComputer<Features> {
  final bool skipEnqueuerCheck;

  const ClosedWorldDataComputer(this.skipEnqueuerCheck);

  @override
  void setup() {
    Enqueuer.skipEnqueuerCheckForTesting = skipEnqueuerCheck;
  }

  /// Compute a short textual representation of [access] on member.
  ///
  /// Dynamic access on instance members and static access on non-instance
  /// members is implicit, so we only annotate super access and static access
  /// not implied by dynamic or super access.
  String computeAccessText(
    MemberEntity member,
    EnumSet<Access> access, [
    String? prefix,
  ]) {
    StringBuffer sb = StringBuffer();
    String delimiter = '';
    if (prefix != null) {
      sb.write(prefix);
      delimiter = ':';
    }
    if (access.contains(Access.superAccess)) {
      sb.write(delimiter);
      sb.write('super');
    } else if (member.isInstanceMember &&
        access.contains(Access.staticAccess) &&
        !access.contains(Access.dynamicAccess)) {
      sb.write(delimiter);
      sb.write('static');
    }
    return sb.toString();
  }

  @override
  void computeMemberData(
    Compiler compiler,
    MemberEntity member,
    Map<Id, ActualData<Features>> actualMap, {
    bool verbose = false,
  }) {
    KernelFrontendStrategy frontendStrategy = compiler.frontendStrategy;
    ResolutionWorldBuilder resolutionWorldBuilder =
        compiler.resolutionWorldBuilderForTesting!;
    ir.Member node = frontendStrategy.elementMap.getMemberNode(member);
    Features features = Features();
    MemberUsage? memberUsage =
        resolutionWorldBuilder.memberUsageForTesting[member];
    if (memberUsage != null) {
      if (member is FieldEntity && memberUsage.hasInit) {
        features.add(Tags.init);
      }
      if (memberUsage.hasRead) {
        features[Tags.read] = computeAccessText(member, memberUsage.reads);
      }
      if (memberUsage.hasWrite) {
        features[Tags.write] = computeAccessText(member, memberUsage.writes);
      }
      if (memberUsage.hasInvoke) {
        if (memberUsage is MethodUsage &&
            !memberUsage.parameterUsage.isFullyUsed) {
          features[Tags.invoke] = computeAccessText(
            member,
            memberUsage.invokes,
            memberUsage.invokedParameters!.shortText,
          );
        } else {
          features[Tags.invoke] = computeAccessText(
            member,
            memberUsage.invokes,
          );
        }
      }
    }
    Id id = computeMemberId(node);
    ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node)!;
    actualMap[id] = ActualData<Features>(
      id,
      features,
      nodeWithOffset.location!.file,
      nodeWithOffset.fileOffset,
      member,
    );
  }

  @override
  bool get testFrontend => true;

  @override
  DataInterpreter<Features> get dataValidator =>
      const FeaturesDataInterpreter();
}
