// 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:async_helper/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/ir/util.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:compiler/src/util/features.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 = new Directory.fromUri(Platform.script.resolve('data'));
    print('------------------------------------------------------------------');
    print(' Test with enqueuer checks');
    print('------------------------------------------------------------------');
    await checkTests(dataDir, const ClosedWorldDataComputer(false),
        args: args, testOmit: false, testCFEConstants: true);
    print('------------------------------------------------------------------');
    print(' Test without enqueuer checks');
    print('------------------------------------------------------------------');
    await checkTests(dataDir, const ClosedWorldDataComputer(true),
        args: args, testOmit: false, testCFEConstants: true);
  });
}

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 = new 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;
    ResolutionWorldBuilderImpl resolutionWorldBuilder =
        compiler.resolutionWorldBuilder;
    ir.Member node = frontendStrategy.elementMap.getMemberNode(member);
    Features features = new Features();
    MemberUsage memberUsage =
        resolutionWorldBuilder.memberUsageForTesting[member];
    if (memberUsage != null) {
      if (member.isField && 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 = computeEntityId(node);
    actualMap[id] = new ActualData<Features>(
        id, features, computeSourceSpanFromTreeNode(node), member);
  }

  @override
  bool get testFrontend => true;

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