/*
 * 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.search.BlazePackage;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import java.lang.reflect.Array;
import java.util.Arrays;
import javax.annotation.Nullable;
import javax.swing.Icon;

/** Base PSI class for the BUILD language */
public abstract class BuildElementImpl extends ASTWrapperPsiElement implements BuildElement {

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

  public <P extends PsiElement> P getPsiChild(IElementType type, Class<P> psiClass) {
    ASTNode childNode = getNode().findChildByType(type);
    return childNode != null ? (P) childNode.getPsi() : null;
  }

  @Override
  public <P extends PsiElement> P[] childrenOfClass(Class<P> psiClass) {
    return findChildrenByClass(psiClass);
  }

  @Nullable
  @Override
  public <P extends PsiElement> P firstChildOfClass(Class<P> psiClass) {
    return findChildByClass(psiClass);
  }

  /**
   * Returns the BuildElement child at the specified index, where index is calculated after
   * filtering out non-BuildElement children.
   *
   * @return null if index >= number of BuildElement children
   */
  @Nullable
  protected BuildElement getBuildElementChild(int index) {
    BuildElement[] children = buildElementChildren();
    return children.length <= index ? null : children[index];
  }

  public BuildElement[] buildElementChildren() {
    return Arrays.stream(getNode().getChildren(null))
        .map(ASTNode::getPsi)
        .filter(psiElement -> psiElement instanceof BuildElement)
        .toArray(BuildElement[]::new);
  }

  protected <T extends BuildElement> T[] childrenToPsi(TokenSet filterSet, T[] array) {
    final ASTNode[] nodes = getNode().getChildren(filterSet);
    T[] psiElements = (T[]) Array.newInstance(array.getClass().getComponentType(), nodes.length);
    for (int i = 0; i < nodes.length; i++) {
      psiElements[i] = (T) nodes[i].getPsi();
    }
    return psiElements;
  }

  /** Finds the n'th child of the specified type */
  @Nullable
  protected PsiElement childToPsi(TokenSet filterSet, int index) {
    final ASTNode[] nodes = getNode().getChildren(filterSet);
    if (nodes.length <= index) {
      return null;
    }
    return nodes[index].getPsi();
  }

  @Nullable
  protected IElementType getParentType() {
    ASTNode node = getNode().getTreeParent();
    return node != null ? node.getElementType() : null;
  }

  public String nonNullName() {
    String name = getName();
    return name != null ? name : "<unnamed>";
  }

  @Override
  public String getPresentableText() {
    return nonNullName();
  }

  @Override
  public String toString() {
    return super.toString() + ": " + getPresentableText();
  }

  @Override
  public void accept(PsiElementVisitor visitor) {
    if (visitor instanceof BuildElementVisitor) {
      acceptVisitor(((BuildElementVisitor) visitor));
    } else {
      super.accept(visitor);
    }
  }

  protected abstract void acceptVisitor(BuildElementVisitor visitor);

  @Nullable
  @Override
  public PsiElement getReferencedElement() {
    PsiReference[] refs = getReferences();
    for (PsiReference ref : refs) {
      PsiElement element = ref.resolve();
      if (element != null) {
        return element;
      }
    }
    return null;
  }

  @Override
  public ItemPresentation getPresentation() {
    final BuildElement element = this;
    return new ItemPresentation() {
      @Override
      public String getPresentableText() {
        return element.getPresentableText();
      }

      @Override
      public String getLocationString() {
        return null;
      }

      @Override
      public Icon getIcon(boolean unused) {
        return element.getIcon(0);
      }
    };
  }

  @Nullable
  @Override
  public BlazePackage getBlazePackage() {
    PsiFile file = getContainingFile();
    return file != null ? BlazePackage.getContainingPackage(file) : null;
  }

  @Nullable
  @Override
  public BuildFile getContainingFile() {
    return (BuildFile) super.getContainingFile();
  }
}
