// Copyright (c) 2015, 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.

// TODO(johnniwinther): Remove this library when all constant constructors are
// computed during resolution.
library dart2js.constants.constant_constructors;

import '../common.dart';
import '../dart_types.dart';
import '../elements/elements.dart';
import '../resolution/operators.dart';
import '../resolution/semantic_visitor.dart';
import '../resolution/send_resolver.dart' show
    DeclarationResolverMixin;
import '../resolution/send_structure.dart';
import '../resolution/tree_elements.dart' show
    TreeElements;
import '../tree/tree.dart';
import '../universe/call_structure.dart' show
    CallStructure;

import 'constructors.dart';
import 'expressions.dart';

ConstantConstructor computeConstantConstructor(ResolvedAst resolvedAst) {
  ConstantConstructorComputer visitor =
      new ConstantConstructorComputer(resolvedAst.elements);
  return resolvedAst.node.accept(visitor);
}

class ConstantConstructorComputer extends SemanticVisitor
    with SemanticDeclarationResolvedMixin,
         DeclarationResolverMixin,
         GetBulkMixin,
         SetBulkMixin,
         ErrorBulkMixin,
         InvokeBulkMixin,
         IndexSetBulkMixin,
         CompoundBulkMixin,
         SetIfNullBulkMixin,
         UnaryBulkMixin,
         BaseBulkMixin,
         BinaryBulkMixin,
         PrefixBulkMixin,
         PostfixBulkMixin,
         NewBulkMixin,
         InitializerBulkMixin,
         FunctionBulkMixin,
         VariableBulkMixin
    implements SemanticDeclarationVisitor, SemanticSendVisitor {
  final Map<FieldElement, ConstantExpression> fieldMap =
      <FieldElement, ConstantExpression>{};
  final Map<dynamic/*int|String*/, ConstantExpression> defaultValues =
      <dynamic/*int|String*/, ConstantExpression>{};

  ConstantConstructorComputer(TreeElements elements)
      : super(elements);

  SemanticDeclarationVisitor get declVisitor => this;

  SemanticSendVisitor get sendVisitor => this;

  ClassElement get currentClass => currentConstructor.enclosingClass;

  ConstructorElement get currentConstructor => elements.analyzedElement;

  apply(Node node, [_]) => node.accept(this);

  visitNode(Node node) {
    internalError(node, 'Unhandled node $node: ${node.toDebugString()}');
  }

  @override
  bulkHandleNode(Node node, String template, _) {
    internalError(node, template.replaceFirst('#' , '$node'));
  }

  internalError(Node node, String message) {
    throw new UnsupportedError(message);
  }

  ConstantConstructor visitGenerativeConstructorDeclaration(
        FunctionExpression node,
        ConstructorElement constructor,
        NodeList parameters,
        NodeList initializers,
        Node body,
        _) {
    applyParameters(parameters, _);
    ConstructedConstantExpression constructorInvocation =
        applyInitializers(node, _);
    return new GenerativeConstantConstructor(
        currentClass.thisType, defaultValues, fieldMap, constructorInvocation);
  }

  ConstantConstructor visitRedirectingGenerativeConstructorDeclaration(
      FunctionExpression node,
      ConstructorElement constructor,
      NodeList parameters,
      NodeList initializers,
      _) {
    applyParameters(parameters, _);
    ConstructedConstantExpression constructorInvocation =
        applyInitializers(node, _);
    return new RedirectingGenerativeConstantConstructor(
        defaultValues, constructorInvocation);
  }

  ConstantConstructor visitRedirectingFactoryConstructorDeclaration(
      FunctionExpression node,
      ConstructorElement constructor,
      NodeList parameters,
      InterfaceType redirectionType,
      ConstructorElement redirectionTarget,
      _) {
    List<String> argumentNames = [];
    List<ConstantExpression> arguments = [];
    int index = 0;
    for (ParameterElement parameter in constructor.parameters) {
      if (parameter.isNamed) {
        String name = parameter.name;
        argumentNames.add(name);
        arguments.add(new NamedArgumentReference(name));
      } else {
        arguments.add(new PositionalArgumentReference(index));
      }
      index++;
    }
    CallStructure callStructure = new CallStructure(index, argumentNames);

    return new RedirectingFactoryConstantConstructor(
        new ConstructedConstantExpression(
            redirectionType,
            redirectionTarget,
            callStructure,
            arguments));
  }

  @override
  visitFactoryConstructorDeclaration(
      FunctionExpression node,
      ConstructorElement constructor,
      NodeList parameters,
      Node body, _) {
    // TODO(johnniwinther): Handle constant constructors with errors.
    internalError(node, "Factory constructor cannot be constant: $node.");
  }

  applyParameters(NodeList parameters, _) {
    computeParameterStructures(parameters).forEach((s) => s.dispatch(this, _));
  }

  visitParameterDeclaration(
      VariableDefinitions node,
      Node definition,
      ParameterElement parameter,
      int index,
      _) {
    // Do nothing.
  }

  visitOptionalParameterDeclaration(
      VariableDefinitions node,
      Node definition,
      ParameterElement parameter,
      ConstantExpression defaultValue,
      int index,
      _) {
    assert(invariant(node, defaultValue != null));
    defaultValues[index] = defaultValue;
  }

  visitNamedParameterDeclaration(
      VariableDefinitions node,
      Node definition,
      ParameterElement parameter,
      ConstantExpression defaultValue,
      _) {
    assert(invariant(node, defaultValue != null));
    String name = parameter.name;
    defaultValues[name] = defaultValue;
  }

  visitInitializingFormalDeclaration(
      VariableDefinitions node,
      Node definition,
      InitializingFormalElement parameter,
      int index,
      _) {
    fieldMap[parameter.fieldElement] = new PositionalArgumentReference(index);
  }

  visitOptionalInitializingFormalDeclaration(
      VariableDefinitions node,
      Node definition,
      InitializingFormalElement parameter,
      ConstantExpression defaultValue,
      int index,
      _) {
    assert(invariant(node, defaultValue != null));
    defaultValues[index] = defaultValue;
    fieldMap[parameter.fieldElement] = new PositionalArgumentReference(index);
  }

  visitNamedInitializingFormalDeclaration(
      VariableDefinitions node,
      Node definition,
      InitializingFormalElement parameter,
      ConstantExpression defaultValue,
      _) {
    assert(invariant(node, defaultValue != null));
    String name = parameter.name;
    defaultValues[name] = defaultValue;
    fieldMap[parameter.fieldElement] = new NamedArgumentReference(name);
  }

  /// Apply this visitor to the constructor [initializers].
  ConstructedConstantExpression applyInitializers(
      FunctionExpression constructor, _) {
    ConstructedConstantExpression constructorInvocation;
    InitializersStructure initializers =
        computeInitializersStructure(constructor);
    for (InitializerStructure structure in initializers.initializers) {
      if (structure.isConstructorInvoke) {
        constructorInvocation = structure.dispatch(this, _);
      } else {
        structure.dispatch(this, _);
      }
    }
    return constructorInvocation;
  }

  visitFieldInitializer(
      SendSet node,
      FieldElement field,
      Node initializer,
      _) {
    fieldMap[field] = apply(initializer);
  }

  visitParameterGet(
      Send node,
      ParameterElement parameter,
      _) {
    if (parameter.isNamed) {
      return new NamedArgumentReference(parameter.name);
    } else {
      return new PositionalArgumentReference(
          parameter.functionDeclaration.parameters.indexOf(parameter));
    }
  }

  ConstructedConstantExpression visitSuperConstructorInvoke(
      Send node,
      ConstructorElement superConstructor,
      InterfaceType type,
      NodeList arguments,
      CallStructure callStructure,
      _) {
    List<ConstantExpression> argumentExpression =
        arguments.nodes.map((a) => apply(a)).toList();
    return new ConstructedConstantExpression(
        type,
        superConstructor,
        callStructure,
        argumentExpression);
  }

  ConstructedConstantExpression visitImplicitSuperConstructorInvoke(
      FunctionExpression node,
      ConstructorElement superConstructor,
      InterfaceType type,
      _) {
     return new ConstructedConstantExpression(
         type,
         superConstructor,
         CallStructure.NO_ARGS,
         const <ConstantExpression>[]);
  }

  ConstructedConstantExpression visitThisConstructorInvoke(
      Send node,
      ConstructorElement thisConstructor,
      NodeList arguments,
      CallStructure callStructure,
      _) {
    List<ConstantExpression> argumentExpression =
        arguments.nodes.map((a) => apply(a)).toList();
    return new ConstructedConstantExpression(
        currentClass.thisType,
        thisConstructor,
        callStructure,
        argumentExpression);
  }

  @override
  ConstantExpression visitBinary(
      Send node,
      Node left,
      BinaryOperator operator,
      Node right,
      _) {
    return new BinaryConstantExpression(
        apply(left), operator, apply(right));
  }


  @override
  ConstantExpression visitUnary(
      Send node,
      UnaryOperator operator,
      Node expression,
      _) {
    return new UnaryConstantExpression(
        operator, apply(expression));
  }

  @override
  ConstantExpression visitStaticFieldGet(
      Send node,
      FieldElement field,
      _) {
    return new VariableConstantExpression(field);
  }

  @override
  ConstantExpression visitTopLevelFieldGet(
      Send node,
      FieldElement field,
      _) {
    return new VariableConstantExpression(field);
  }

  @override
  ConstantExpression visitLiteralInt(LiteralInt node) {
    return new IntConstantExpression(node.value);
  }

  @override
  ConstantExpression visitLiteralBool(LiteralBool node) {
    return new BoolConstantExpression(node.value);
  }

  @override
  ConstantExpression visitLiteralNull(LiteralNull node) {
    return new NullConstantExpression();
  }

  @override
  ConstantExpression visitLiteralString(LiteralString node) {
    return new StringConstantExpression(node.dartString.slowToString());
  }

  @override
  ConstantExpression visitConditional(Conditional node) {
    return new ConditionalConstantExpression(
        apply(node.condition),
        apply(node.thenExpression),
        apply(node.elseExpression));
  }

  @override
  ConstantExpression visitParenthesizedExpression(ParenthesizedExpression node) {
    return apply(node.expression);
  }

  @override
  ConstantExpression visitTopLevelFunctionInvoke(
      Send node,
      MethodElement function,
      NodeList arguments,
      CallStructure callStructure,
      _) {
    if (function.name != 'identical' || !function.library.isDartCore) {
      throw new UnsupportedError("Unexpected function call: $function");
    }
    return new IdenticalConstantExpression(
        apply(arguments.nodes.head), apply(arguments.nodes.tail.head));
  }

  @override
  ConstantExpression visitNamedArgument(NamedArgument node) {
    return apply(node.expression);
  }
}