// 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 'dart:io';
import 'package:_fe_analyzer_shared/src/testing/features.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/closure.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/common/codegen.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/js_model/element_map.dart';
import 'package:compiler/src/js_model/js_world.dart';
import 'package:kernel/ast.dart' as ir;
import '../equivalence/id_equivalence.dart';
import '../equivalence/id_equivalence_helper.dart';
import '../helpers/program_lookup.dart';

main(List<String> args) {
  asyncTest(() async {
    Directory dataDir =
        new Directory.fromUri(Platform.script.resolve('model_data'));
    await checkTests(dataDir, const ModelDataComputer(),
        args: args, testedConfigs: allInternalConfigs);
  });
}

class ModelDataComputer extends DataComputer<Features> {
  const ModelDataComputer();

  /// Compute type inference data for [member] from kernel based inference.
  ///
  /// Fills [actualMap] with the data.
  @override
  void computeMemberData(Compiler compiler, MemberEntity member,
      Map<Id, ActualData<Features>> actualMap,
      {bool verbose: false}) {
    JsClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
    JsToElementMap elementMap = closedWorld.elementMap;
    MemberDefinition definition = elementMap.getMemberDefinition(member);
    new ModelIrComputer(compiler.reporter, actualMap, elementMap, member,
            compiler, closedWorld.closureDataLookup)
        .run(definition.node);
  }

  @override
  DataInterpreter<Features> get dataValidator =>
      const FeaturesDataInterpreter(wildcard: '*');
}

class Tags {
  static const String needsCheckedSetter = 'checked';
  static const String getterFlags = 'get';
  static const String setterFlags = 'set';
  static const String parameterCount = 'params';
  static const String call = 'calls';
  static const String parameterStub = 'stubs';
  static const String callStubCall = 'stubCalls';
  static const String callStubAccesses = 'stubAccesses';
  static const String isEmitted = 'emitted';
  static const String isElided = 'elided';
  static const String assignment = 'assign';
  static const String isLazy = 'lazy';
  static const String propertyAccess = 'access';
  static const String switchCase = 'switch';
}

/// AST visitor for computing inference data for a member.
class ModelIrComputer extends IrDataExtractor<Features> {
  final JsToElementMap _elementMap;
  final ClosureData _closureDataLookup;
  final ProgramLookup _programLookup;

  ModelIrComputer(
      DiagnosticReporter reporter,
      Map<Id, ActualData<Features>> actualMap,
      this._elementMap,
      MemberEntity member,
      Compiler compiler,
      this._closureDataLookup)
      : _programLookup = new ProgramLookup(compiler.backendStrategy),
        super(reporter, actualMap);

  void registerCalls(Features features, String tag, js.Node node,
      {String prefix = '', Set<js.PropertyAccess> handledAccesses}) {
    forEachNode(node, onCall: (js.Call node) {
      js.Node target = undefer(node.target);
      if (target is js.PropertyAccess) {
        js.Node selector = undefer(target.selector);
        bool fixedNameCall = false;
        String name;
        if (selector is js.Name) {
          name = selector.key;
        } else if (selector is js.LiteralString) {
          /// Call to fixed backend name, so we include the argument
          /// values to test encoding of optional parameters in native
          /// methods.
          name = selector.value;
          fixedNameCall = true;
        }
        if (name != null) {
          if (fixedNameCall) {
            String arguments = node.arguments.map(js.nodeToString).join(',');
            features.addElement(tag, '${prefix}${name}(${arguments})');
          } else {
            features.addElement(
                tag, '${prefix}${name}(${node.arguments.length})');
          }
          handledAccesses?.add(target);
        }
      }
    });
  }

  void registerAccesses(Features features, String tag, js.Node code,
      {String prefix = '', Set<js.PropertyAccess> handledAccesses}) {
    forEachNode(code, onPropertyAccess: (js.PropertyAccess node) {
      if (handledAccesses?.contains(node) ?? false) {
        return;
      }

      js.Node receiver = undefer(node.receiver);
      String receiverName;
      if (receiver is js.VariableUse) {
        receiverName = receiver.name;
        if (receiverName == receiverName.toUpperCase() &&
            receiverName != r'$') {
          // Skip holder access.
          receiverName = null;
        }
      } else if (receiver is js.This) {
        receiverName = 'this';
      }

      js.Node selector = undefer(node.selector);
      String name;
      if (selector is js.Name) {
        name = selector.key;
      } else if (selector is js.LiteralString) {
        /// Call to fixed backend name, so we include the argument
        /// values to test encoding of optional parameters in native
        /// methods.
        name = selector.value;
      }

      if (receiverName != null && name != null) {
        features.addElement(tag, '${prefix}${name}');
      }
    });
  }

  Features getMemberValue(MemberEntity member) {
    if (member is FieldEntity) {
      Field field = _programLookup.getField(member);
      if (field != null) {
        Features features = new Features();
        if (field.needsCheckedSetter) {
          features.add(Tags.needsCheckedSetter);
        }
        if (field.isElided) {
          features.add(Tags.isElided);
        } else {
          features.add(Tags.isEmitted);
        }
        void registerFlags(String tag, int flags) {
          switch (flags) {
            case 0:
              break;
            case 1:
              features.add(tag, value: 'simple');
              break;
            case 2:
              features.add(tag, value: 'intercepted');
              break;
            case 3:
              features.add(tag, value: 'interceptedThis');
              break;
          }
        }

        registerFlags(Tags.getterFlags, field.getterFlags);
        registerFlags(Tags.setterFlags, field.setterFlags);

        Class cls = _programLookup.getClass(member.enclosingClass);
        for (StubMethod stub in cls.callStubs) {
          if (stub.element == member) {
            registerCalls(features, Tags.callStubCall, stub.code,
                prefix: '${stub.name.key}:');
            registerAccesses(features, Tags.callStubAccesses, stub.code,
                prefix: '${stub.name.key}:');
          }
        }

        return features;
      }
      StaticField staticField = _programLookup.getStaticField(member);
      if (staticField != null) {
        Features features = new Features();
        features.add(Tags.isEmitted);
        if (staticField.isLazy) {
          features.add(Tags.isLazy);
        }
        return features;
      }
    } else if (member is FunctionEntity) {
      Method method = _programLookup.getMethod(member);
      if (method != null) {
        Features features = new Features();
        js.Expression code = method.code;
        if (code is js.Fun) {
          features[Tags.parameterCount] = '${code.params.length}';
        }

        Set<js.PropertyAccess> handledAccesses = new Set();

        registerCalls(features, Tags.call, code,
            handledAccesses: handledAccesses);
        if (method is DartMethod) {
          for (ParameterStubMethod stub in method.parameterStubs) {
            registerCalls(features, Tags.parameterStub, stub.code,
                prefix: '${stub.name.key}:', handledAccesses: handledAccesses);
          }
        }

        forEachNode(code, onAssignment: (js.Assignment node) {
          js.Expression leftHandSide = undefer(node.leftHandSide);
          if (leftHandSide is js.PropertyAccess) {
            js.Node selector = undefer(leftHandSide.selector);
            String name;
            if (selector is js.Name) {
              name = selector.key;
            } else if (selector is js.LiteralString) {
              name = selector.value;
            }
            if (name != null) {
              features.addElement(Tags.assignment, '${name}');
              handledAccesses.add(leftHandSide);
            }
          }
        });

        registerAccesses(features, Tags.propertyAccess, code,
            handledAccesses: handledAccesses);

        forEachNode(code, onSwitch: (js.Switch node) {
          features.add(Tags.switchCase);
        });

        return features;
      }
    }
    return null;
  }

  @override
  Features computeMemberValue(Id id, ir.Member node) {
    return getMemberValue(_elementMap.getMember(node));
  }

  @override
  Features computeNodeValue(Id id, ir.TreeNode node) {
    if (node is ir.FunctionExpression || node is ir.FunctionDeclaration) {
      ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
      return getMemberValue(info.callMethod);
    }
    return null;
  }
}

js.Node undefer(js.Node node) {
  if (node is js.DeferredExpression) return undefer(node.value);
  if (node is ModularName) return undefer(node.value);
  return node;
}
