/*
 * 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.google.idea.blaze.base.model.primitives.WorkspacePath;
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;
  }

  @Nullable
  protected <T extends BuildElement> T childToPsi(TokenSet filterSet, int index) {
    final ASTNode[] nodes = getNode().getChildren(filterSet);
    if (nodes.length <= index) {
      return null;
    }
    return (T) 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 WorkspacePath getWorkspacePath() {
    BuildFile file = (BuildFile) getContainingFile();
    return file.getWorkspacePath();
  }

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

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