// Copyright (c) 2014, 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 dart2js.resolution.enum_creator;

import '../compiler.dart';
import '../dart_types.dart';
import '../elements/elements.dart';
import '../elements/modelx.dart';
import '../tokens/keyword.dart' show
    Keyword;
import '../tokens/precedence.dart';
import '../tokens/precedence_constants.dart' as Precedence;
import '../tokens/token.dart';
import '../tree/tree.dart';
import '../util/util.dart';

// TODO(johnniwinther): Merge functionality with the `TreePrinter`.
class AstBuilder {
  final int charOffset;

  AstBuilder(this.charOffset);

  Modifiers modifiers({bool isConst: false,
                       bool isFinal: false,
                       bool isStatic: false}) {
    List identifiers = [];
    int flags = 0;
    if (isConst) {
      identifiers.add(identifier('const'));
      flags |= Modifiers.FLAG_CONST;
    }
    if (isFinal) {
      identifiers.add(identifier('final'));
      flags |= Modifiers.FLAG_FINAL;
    }
    if (isStatic) {
      identifiers.add(identifier('static'));
      flags |= Modifiers.FLAG_STATIC;
    }
    return new Modifiers.withFlags(
        new NodeList(null, linkedList(identifiers), null, ''),
        flags);
  }

  Token keywordToken(String text) {
    return new KeywordToken(Keyword.keywords[text], charOffset);
  }

  Token stringToken(String text) {
    return new StringToken.fromString(
        Precedence.IDENTIFIER_INFO, text, charOffset);
  }

  Token symbolToken(PrecedenceInfo info) {
    return new SymbolToken(info, charOffset);
  }

  Identifier identifier(String text) {
    Keyword keyword = Keyword.keywords[text];
    Token token;
    if (keyword != null) {
      token = new KeywordToken(Keyword.keywords[text], charOffset);
    } else {
      token = stringToken(text);
    }
    return new Identifier(token);
  }

  Link linkedList(List elements) {
    LinkBuilder builder = new LinkBuilder();
    elements.forEach((e) => builder.addLast(e));
    return builder.toLink();
  }

  NodeList argumentList(List<Node> nodes) {
    return new NodeList(symbolToken(Precedence.OPEN_PAREN_INFO),
                        linkedList(nodes),
                        symbolToken(Precedence.CLOSE_PAREN_INFO),
                        ',');
  }

  Return returnStatement(Expression expression) {
    return new Return(
        keywordToken('return'),
        symbolToken(Precedence.SEMICOLON_INFO),
        expression);
  }

  FunctionExpression functionExpression(Modifiers modifiers,
                                        String name,
                                        NodeList argumentList,
                                        Statement body,
                                        [TypeAnnotation returnType]) {
    return new FunctionExpression(
        identifier(name),
        argumentList,
        body,
        returnType,
        modifiers,
        null, // Initializer.
        null, // get/set.
        null  // Async modifier.
        );
  }

  EmptyStatement emptyStatement() {
    return new EmptyStatement(symbolToken(Precedence.COMMA_INFO));
  }

  LiteralInt literalInt(int value) {
    return new LiteralInt(stringToken('$value'), null);
  }

  LiteralString literalString(String text,
                              {String prefix: '"',
                                String suffix: '"'}) {
    return new LiteralString(stringToken('$prefix$text$suffix'),
                             new DartString.literal(text));
  }

  LiteralList listLiteral(List<Node> elements, {bool isConst: false}) {
    return new LiteralList(
        null,
        new NodeList(symbolToken(Precedence.OPEN_SQUARE_BRACKET_INFO),
                     linkedList(elements),
                     symbolToken(Precedence.CLOSE_SQUARE_BRACKET_INFO),
                     ','),
        isConst ? keywordToken('const') : null);
  }

  Node createDefinition(Identifier name, Expression initializer) {
    if (initializer == null) return name;
    return new SendSet(null, name,
        new Operator(symbolToken(Precedence.EQ_INFO)),
            new NodeList.singleton(initializer));
  }

  VariableDefinitions initializingFormal(String fieldName) {
    return new VariableDefinitions.forParameter(
        new NodeList.empty(),
        null,
        Modifiers.EMPTY,
        new NodeList.singleton(
            new Send(identifier('this'), identifier(fieldName))));
  }

  NewExpression newExpression(String typeName,
                              NodeList arguments,
                              {bool isConst: false}) {
    return new NewExpression(keywordToken(isConst ? 'const' : 'new'),
        new Send(null, identifier(typeName), arguments));
  }

  Send reference(Identifier identifier) {
    return new Send(null, identifier);
  }

  Send indexGet(Expression receiver, Expression index) {
    return new Send(receiver,
                    new Operator(symbolToken(Precedence.INDEX_INFO)),
                    new NodeList.singleton(index));
  }

  LiteralMapEntry mapLiteralEntry(Expression key, Expression value) {
    return new LiteralMapEntry(key, symbolToken(Precedence.COLON_INFO), value);
  }

  LiteralMap mapLiteral(List<LiteralMapEntry> entries, {bool isConst: false}) {
    return new LiteralMap(
        null, // Type arguments.
        new NodeList(symbolToken(Precedence.OPEN_CURLY_BRACKET_INFO),
                     linkedList(entries),
                     symbolToken(Precedence.CLOSE_CURLY_BRACKET_INFO),
                     ','),
        isConst ? keywordToken('const') : null);
  }
}

class EnumCreator {
  final Compiler compiler;
  final EnumClassElementX enumClass;

  EnumCreator(this.compiler, this.enumClass);

  void createMembers() {
    Enum node = enumClass.node;
    InterfaceType enumType = enumClass.thisType;
    AstBuilder builder = new AstBuilder(enumClass.position.charOffset);

    InterfaceType intType = compiler.intClass.computeType(compiler);
    InterfaceType stringType = compiler.stringClass.computeType(compiler);

    EnumFieldElementX addInstanceMember(String name, InterfaceType type) {
      Identifier identifier = builder.identifier(name);
      VariableList variableList =
          new VariableList(builder.modifiers(isFinal: true));
      variableList.type = type;
      EnumFieldElementX variable = new EnumFieldElementX(
          identifier, enumClass, variableList, identifier);
      enumClass.addMember(variable, compiler);
      return variable;
    }

    EnumFieldElementX indexVariable = addInstanceMember('index', intType);

    VariableDefinitions indexDefinition = builder.initializingFormal('index');

    FunctionExpression constructorNode = builder.functionExpression(
        builder.modifiers(isConst: true),
        enumClass.name,
        builder.argumentList([indexDefinition]),
        builder.emptyStatement());

    EnumConstructorElementX constructor = new EnumConstructorElementX(
        enumClass,
        builder.modifiers(isConst: true),
        constructorNode);

    EnumFormalElementX indexFormal = new EnumFormalElementX(
        constructor,
        indexDefinition,
        builder.identifier('index'),
        indexVariable);

    FunctionSignatureX constructorSignature = new FunctionSignatureX(
        requiredParameters: [indexFormal],
        requiredParameterCount: 1,
        type: new FunctionType(constructor, const VoidType(),
            <DartType>[intType]));
    constructor.functionSignatureCache = constructorSignature;
    enumClass.addMember(constructor, compiler);

    List<FieldElement> enumValues = <FieldElement>[];
    VariableList variableList =
        new VariableList(builder.modifiers(isStatic: true, isConst: true));
    variableList.type = enumType;
    int index = 0;
    List<Node> valueReferences = <Node>[];
    List<LiteralMapEntry> mapEntries = <LiteralMapEntry>[];
    for (Link<Node> link = node.names.nodes;
         !link.isEmpty;
         link = link.tail) {
      Identifier name = link.head;
      AstBuilder valueBuilder = new AstBuilder(name.token.charOffset);

      // Add reference for the `values` field.
      valueReferences.add(valueBuilder.reference(name));

      // Add map entry for `toString` implementation.
      mapEntries.add(valueBuilder.mapLiteralEntry(
            valueBuilder.literalInt(index),
            valueBuilder.literalString('${enumClass.name}.${name.source}')));

      Expression initializer = valueBuilder.newExpression(
          enumClass.name,
          valueBuilder.argumentList([valueBuilder.literalInt(index)]),
          isConst: true);
      SendSet definition = valueBuilder.createDefinition(name, initializer);

      EnumFieldElementX field = new EnumFieldElementX(
          name, enumClass, variableList, definition, initializer);
      enumValues.add(field);
      enumClass.addMember(field, compiler);
      index++;
    }

    VariableList valuesVariableList =
        new VariableList(builder.modifiers(isStatic: true, isConst: true));
    InterfaceType listType = compiler.listClass.computeType(compiler);
    valuesVariableList.type = listType.createInstantiation([enumType]);

    Identifier valuesIdentifier = builder.identifier('values');
    // TODO(johnniwinther): Add type argument.
    Expression initializer = builder.listLiteral(
        valueReferences, isConst: true);

    Node definition = builder.createDefinition(valuesIdentifier, initializer);

    EnumFieldElementX valuesVariable = new EnumFieldElementX(
        valuesIdentifier, enumClass, valuesVariableList,
        definition, initializer);

    enumClass.addMember(valuesVariable, compiler);

    // TODO(johnniwinther): Support return type. Note `String` might be prefixed
    // or not imported within the current library.
    FunctionExpression toStringNode = builder.functionExpression(
        Modifiers.EMPTY,
        'toString',
        builder.argumentList([]),
        builder.returnStatement(
              builder.indexGet(
                  builder.mapLiteral(mapEntries, isConst: true),
                  builder.reference(builder.identifier('index')))
            )
        );

    EnumMethodElementX toString = new EnumMethodElementX('toString',
        enumClass, Modifiers.EMPTY, toStringNode);
    FunctionSignatureX toStringSignature = new FunctionSignatureX(
        type: new FunctionType(toString, stringType));
    toString.functionSignatureCache = toStringSignature;
    enumClass.addMember(toString, compiler);

    enumClass.enumValues = enumValues;
  }
}