// 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/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/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/js_backend/namer.dart';
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:compiler/src/util/features.dart';
import 'package:js_ast/js_ast.dart' as js;
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, testCFEConstants: true);
  });
}

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();
}

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;
          fixedNameCall = selector is StringBackedName;
        } 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.substring(1, selector.value.length - 1);
          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.substring(1, selector.value.length - 1);
      }

      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.substring(1, selector.value.length - 1);
            }
            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;
}
