/*
 * 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 javax.annotation.Nullable;
import javax.swing.*;
import java.lang.reflect.Array;
import java.util.Arrays;

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

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

  protected 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();
  }
}
