/*
 * 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.*;

/**
 * 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() {
    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");
  }

  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];
  }

}
