/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.idea.blaze.base.lang.buildfile.psi;

import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpec;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpecProvider;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.google.idea.blaze.base.lang.buildfile.references.FuncallReference;
import com.google.idea.blaze.base.lang.buildfile.references.LabelUtils;
import com.google.idea.blaze.base.model.primitives.Label;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNameIdentifierOwner;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import icons.BlazeIcons;
import javax.annotation.Nullable;
import javax.swing.Icon;

/**
 * PSI element for an function call.<br>
 * Could be a top-level rule, Skylark function reference, or general some other python function call
 */
public class FuncallExpression extends BuildElementImpl
    implements Expression, PsiNameIdentifierOwner {

  public FuncallExpression(ASTNode astNode) {
    super(astNode);
  }

  @Override
  protected void acceptVisitor(BuildElementVisitor visitor) {
    visitor.visitFuncallExpression(this);
  }

  /** The name of the function being called. */
  @Nullable
  public String getFunctionName() {
    ASTNode node = getFunctionNameNode();
    return node != null ? node.getText() : null;
  }

  @Override
  @Nullable
  public String getName() {
    return getNameArgumentValue();
  }

  @Nullable
  @Override
  public PsiElement getNameIdentifier() {
    Argument.Keyword name = getNameArgument();
    return name != null ? name.getValue() : null;
  }

  @Override
  public PsiElement setName(String name) throws IncorrectOperationException {
    StringLiteral nameNode = getNameArgumentValueNode();
    if (nameNode == null) {
      return this;
    }
    ASTNode newChild = PsiUtils.createNewLabel(getProject(), name);
    nameNode.getNode().replaceChild(nameNode.getNode().getFirstChildNode(), newChild);
    return this;
  }

  /** The function name */
  @Nullable
  public ASTNode getFunctionNameNode() {
    PsiElement argList = getArgList();
    if (argList != null) {
      // We want the reference expr directly prior to the open parenthesis.
      // This accounts for Skylark native.rule calls.
      PsiElement prev = argList.getPrevSibling();
      if (prev instanceof ReferenceExpression) {
        return prev.getNode();
      }
    }
    return getNode().findChildByType(BuildElementTypes.REFERENCE_EXPRESSION);
  }

  /** Top-level funcalls are almost always BUILD rules. */
  public boolean isTopLevel() {
    ASTNode parent = getNode().getTreeParent();
    return parent == null || parent.getElementType() == BuildElementTypes.BUILD_FILE;
  }

  public boolean mightBeBuildRule() {
    return isTopLevel() || getNameArgument() != null;
  }

  @Nullable
  public Label resolveBuildLabel() {
    BuildFile containingFile = getContainingFile();
    if (containingFile == null
        || containingFile.getBlazeFileType() == BuildFile.BlazeFileType.SkylarkExtension) {
      return null;
    }
    return LabelUtils.createLabelFromRuleName(getBlazePackage(), getNameArgumentValue());
  }

  @Nullable
  public ArgumentList getArgList() {
    return findChildByType(BuildElementTypes.ARGUMENT_LIST);
  }

  public Argument[] getArguments() {
    ArgumentList argList = getArgList();
    return argList != null ? argList.getArguments() : Argument.EMPTY_ARRAY;
  }

  /** Keyword argument with name "name", if one is present. */
  @Nullable
  public Argument.Keyword getNameArgument() {
    return getKeywordArgument("name");
  }

  @Nullable
  public Argument.Keyword getKeywordArgument(String name) {
    ArgumentList argList = getArgList();
    return argList != null ? argList.getKeywordArgument(name) : null;
  }

  /** StringLiteral value of keyword argument with name "name", if one is present. */
  @Nullable
  public StringLiteral getNameArgumentValueNode() {
    Argument.Keyword name = getNameArgument();
    Expression expr = name != null ? name.getValue() : null;
    if (expr instanceof StringLiteral) {
      return ((StringLiteral) expr);
    }
    return null;
  }

  /** Value of keyword argument with name "name", if one is present. */
  @Nullable
  public String getNameArgumentValue() {
    StringLiteral node = getNameArgumentValueNode();
    return node != null ? node.getStringContents() : null;
  }

  @Override
  public Icon getIcon(int flags) {
    return mightBeBuildRule() ? BlazeIcons.BuildRule : null;
  }

  @Override
  public String getPresentableText() {
    String name = getFunctionName();
    if (name == null) {
      return super.getPresentableText();
    }
    String targetName = getNameArgumentValue();
    return targetName != null ? name + "(\"" + targetName + "\")" : name;
  }

  @Override
  @Nullable
  public FuncallReference getReference() {
    ASTNode nameNode = getFunctionNameNode();
    if (nameNode == null) {
      return null;
    }
    BuildLanguageSpec spec = BuildLanguageSpecProvider.getInstance().getLanguageSpec(getProject());
    if (spec != null && spec.hasRule(nameNode.getText())) {
      // don't try to follow references to built-in rules
      return null;
    }
    TextRange range = PsiUtils.childRangeInParent(getTextRange(), nameNode.getTextRange());
    return new FuncallReference(this, range);
  }

  /**
   * Searches all StringLiteral children of this element, for one which references the desired
   * target expression.
   */
  @Nullable
  public StringLiteral findChildReferenceToTarget(final FuncallExpression targetRule) {
    final StringLiteral[] child = new StringLiteral[1];
    Processor<StringLiteral> processor =
        stringLiteral -> {
          PsiElement ref = stringLiteral.getReferencedElement();
          if (targetRule.equals(ref)) {
            child[0] = stringLiteral;
            return false;
          }
          return true;
        };
    PsiUtils.processChildrenOfType(this, processor, StringLiteral.class);
    return child[0];
  }
}
