/*
 * 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.psi.BuildFile.BlazeFileType;
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) {
      return null;
    }
    if (containingFile.getBlazeFileType() != BlazeFileType.BuildPackage) {
      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;
    }
    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];
  }
}
