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

package com.google.dart.compiler.resolver;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.dart.compiler.ast.DartBlock;
import com.google.dart.compiler.ast.DartClass;
import com.google.dart.compiler.ast.DartFunctionExpression;
import com.google.dart.compiler.ast.DartIdentifier;
import com.google.dart.compiler.ast.DartMethodDefinition;
import com.google.dart.compiler.ast.DartNativeBlock;
import com.google.dart.compiler.ast.DartNode;
import com.google.dart.compiler.ast.DartObsoleteMetadata;
import com.google.dart.compiler.ast.Modifiers;
import com.google.dart.compiler.common.SourceInfo;
import com.google.dart.compiler.type.FunctionType;
import com.google.dart.compiler.type.Type;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

class MethodElementImplementation extends AbstractNodeElement implements MethodNodeElement {
  private final DartObsoleteMetadata metadata;
  private final Modifiers modifiers;
  private final EnclosingElement holder;
  private final ElementKind kind;
  private final List<VariableElement> parameters = new ArrayList<VariableElement>();
  private FunctionType type;
  private final SourceInfo nameLocation;
  private final boolean hasBody;
  private Set<Element> overridden = ImmutableSet.of();

  // TODO(ngeoffray): name, return type, argument types.
  @VisibleForTesting
  MethodElementImplementation(DartFunctionExpression node, String name, Modifiers modifiers) {
    super(node, name);
    this.metadata = DartObsoleteMetadata.EMPTY;
    this.modifiers = modifiers;
    this.hasBody = true;
    this.holder = findParentEnclosingElement(node);
    this.kind = ElementKind.FUNCTION_OBJECT;
    if (node != null && node.getName() != null) {
      this.nameLocation = node.getName().getSourceInfo();
    } else {
      this.nameLocation = SourceInfo.UNKNOWN;
    }
  }

  protected MethodElementImplementation(DartMethodDefinition node, String name,
                                        EnclosingElement holder) {
    super(node, name);
    if (node != null) {
      this.metadata = node.getObsoleteMetadata();
      this.modifiers = node.getModifiers();
      this.nameLocation = node.getName().getSourceInfo();
      DartBlock body = node.getFunction().getBody();
      this.hasBody = body != null && !(body instanceof DartNativeBlock);
    } else {
      this.metadata = DartObsoleteMetadata.EMPTY;
      this.modifiers = Modifiers.NONE;
      this.nameLocation = SourceInfo.UNKNOWN;
      this.hasBody = false;
    }
    this.holder = holder;
    this.kind = ElementKind.METHOD;
  }

  @Override
  public DartObsoleteMetadata getMetadata() {
    return metadata;
  }

  @Override
  public Modifiers getModifiers() {
    return modifiers;
  }

  @Override
  public ElementKind getKind() {
    return kind;
  }

  @Override
  public EnclosingElement getEnclosingElement() {
    return holder;
  }

  @Override
  public boolean isConstructor() {
    return false;
  }

  @Override
  public boolean isStatic() {
    return getModifiers().isStatic();
  }

  @Override
  public List<VariableElement> getParameters() {
    return parameters;
  }
  
  @Override
  public boolean hasBody() {
    return hasBody;
  }

  void addParameter(VariableElement parameter) {
    parameters.add(parameter);
  }

  @Override
  public Type getReturnType() {
    return getType().getReturnType();
  }

  @Override
  void setType(Type type) {
    this.type = (FunctionType) type;
  }

  @Override
  public FunctionType getType() {
    return type;
  }

  @Override
  public FunctionType getFunctionType() {
    return getType();
  }

  @Override
  public boolean isInterface() {
    return false;
  }

  @Override
  public Iterable<Element> getMembers() {
    return Collections.emptyList();
  }

  @Override
  public Element lookupLocalElement(String name) {
    return null;
  }

  public static MethodElementImplementation fromMethodNode(DartMethodDefinition node,
                                                           EnclosingElement holder) {
    String targetName;
    if(node.getName() instanceof DartIdentifier) {
      targetName = ((DartIdentifier) node.getName()).getName();
      if (targetName.equals("-") && node.getFunction().getParameters().size() == 1) {
        targetName += "binary";
      }
    } else {
      // Visit the unknown node to generate a string for our use.
      targetName = node.toSource();
    }
    return new MethodElementImplementation(node, targetName, holder);
  }

  public static MethodElementImplementation fromFunctionExpression(DartFunctionExpression node,
                                                                   Modifiers modifiers) {
    return new MethodElementImplementation(node, node.getFunctionName(), modifiers);
  }

  /**
   * @return the innermost {@link EnclosingElement} for given {@link DartNode}, may be
   *         <code>null</code>.
   */
  private static EnclosingElement findParentEnclosingElement(DartNode node) {
    while (node != null && node.getParent() != null) {
      node = node.getParent();
      boolean isEnclosingNode = node instanceof DartClass || node instanceof DartMethodDefinition
          || node instanceof DartFunctionExpression;
      if (isEnclosingNode && node.getElement() instanceof EnclosingElement) {
        return (EnclosingElement) node.getElement();
      }
    }
    return null;
  }
  
  @Override
  public SourceInfo getNameLocation() {
    return nameLocation;
  }

  public void setOverridden(Set<Element> overridden) {
    this.overridden = overridden;
  }
  
  public Set<Element> getOverridden() {
    return overridden;
  }
}
