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

library fasta.transform_set_literals;

import 'dart:core' hide MapEntry;

import 'package:kernel/ast.dart'
    show
        Arguments,
        Class,
        Constructor,
        ConstructorInvocation,
        DartType,
        Expression,
        InterfaceType,
        Let,
        Library,
        MapEntry,
        MapLiteral,
        MethodInvocation,
        Name,
        NullLiteral,
        Procedure,
        SetLiteral,
        StaticInvocation,
        TreeNode,
        VariableDeclaration,
        VariableGet;

import 'package:kernel/core_types.dart' show CoreTypes;

import 'package:kernel/visitor.dart' show Transformer;

import '../source/source_loader.dart' show SourceLoader;

import 'redirecting_factory_body.dart' show RedirectingFactoryBody;

// TODO(askesc): Delete this class when all backends support set literals.
class SetLiteralTransformer extends Transformer {
  final CoreTypes coreTypes;
  final DartType nullType;
  final Procedure setFactory;
  final Procedure addMethod;
  final Constructor unmodifiableSetConstructor;

  static Procedure _findSetFactory(CoreTypes coreTypes) {
    Procedure factory = coreTypes.index.getMember('dart:core', 'Set', '');
    RedirectingFactoryBody body = factory?.function?.body;
    return body?.target;
  }

  static Procedure _findAddMethod(CoreTypes coreTypes) {
    return coreTypes.index.getMember('dart:core', 'Set', 'add');
  }

  static Constructor _findUnmodifiableSetConstructor(SourceLoader loader) {
    // We should not generally dig into libraries like this, and we should
    // avoid dependencies on libraries other than the ones indexed by
    // CoreTypes. This is a temporary solution until all backends have
    // implemented support for set literals.
    Uri collectionUri = Uri.parse("dart:collection");
    Library collectionLibrary = loader.builders[collectionUri].target;
    for (int i = 0; i < collectionLibrary.classes.length; i++) {
      Class classNode = collectionLibrary.classes[i];
      if (classNode.name == "_UnmodifiableSet") {
        for (int j = 0; j < collectionLibrary.classes.length; j++) {
          Constructor constructor = classNode.constructors[j];
          if (constructor.name.name.isEmpty) {
            return constructor;
          }
        }
      }
    }
    return null;
  }

  SetLiteralTransformer(SourceLoader loader)
      : coreTypes = loader.coreTypes,
        nullType = new InterfaceType(loader.coreTypes.nullClass, []),
        setFactory = _findSetFactory(loader.coreTypes),
        addMethod = _findAddMethod(loader.coreTypes),
        unmodifiableSetConstructor = _findUnmodifiableSetConstructor(loader);

  TreeNode visitSetLiteral(SetLiteral node) {
    if (node.isConst) {
      List<MapEntry> entries = new List<MapEntry>(node.expressions.length);
      for (int i = 0; i < node.expressions.length; i++) {
        // expression_i: null
        Expression entry = node.expressions[i].accept(this);
        entries[i] = new MapEntry(entry, new NullLiteral());
      }
      Expression mapExp = new MapLiteral(entries,
          keyType: node.typeArgument, valueType: nullType, isConst: true);
      return new ConstructorInvocation(unmodifiableSetConstructor,
          new Arguments([mapExp], types: [node.typeArgument]),
          isConst: true);
    } else {
      // Outermost declaration of let chain: Set<E> setVar = new Set<E>();
      VariableDeclaration setVar = new VariableDeclaration.forValue(
          new StaticInvocation(
              setFactory, new Arguments([], types: [node.typeArgument])),
          type: new InterfaceType(coreTypes.setClass, [node.typeArgument]));
      // Innermost body of let chain: setVar
      Expression setExp = new VariableGet(setVar);
      for (int i = node.expressions.length - 1; i >= 0; i--) {
        // let _ = setVar.add(expression) in rest
        Expression entry = node.expressions[i].accept(this);
        setExp = new Let(
            new VariableDeclaration.forValue(new MethodInvocation(
                new VariableGet(setVar),
                new Name("add"),
                new Arguments([entry]),
                addMethod)),
            setExp);
      }
      return new Let(setVar, setExp);
    }
  }
}
