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

import com.google.common.collect.Lists;
import com.google.idea.blaze.base.lang.buildfile.psi.AssignmentStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.Expression;
import com.google.idea.blaze.base.lang.buildfile.psi.ReferenceExpression;
import com.google.idea.blaze.base.lang.buildfile.psi.TargetExpression;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;

import javax.annotation.Nullable;
import java.util.List;

/**
 * Utility methods for working with PSI elements
 */
public class PsiUtils {

  public static ASTNode createNewName(Project project, String name) {
    return BuildElementGenerator.getInstance(project).createNameIdentifier(name);
  }

  public static ASTNode createNewLabel(Project project, String labelString) {
    return BuildElementGenerator.getInstance(project).createStringNode(labelString);
  }

  @Nullable
  public static PsiElement getPreviousNodeInTree(PsiElement element) {
    PsiElement prevSibling = null;
    while (element != null && (prevSibling = element.getPrevSibling()) == null) {
      element = element.getParent();
    }
    return prevSibling != null ? lastElementInSubtree(prevSibling) : null;
  }

  /**
   * The last element in the tree rooted at the given element.
   */
  public static PsiElement lastElementInSubtree(PsiElement element) {
    PsiElement lastChild;
    while ((lastChild = element.getLastChild()) != null) {
      element = lastChild;
    }
    return element;
  }

  /**
   * Walks up PSI tree, looking for a parent of the specified class. Stops searching when it reaches a
   * parent of type PsiDirectory.
   */
  @Nullable
  public static <T extends PsiElement> T getParentOfType(PsiElement element, Class<T> psiClass) {
    PsiElement parent = element.getParent();
    while (parent != null && !(parent instanceof PsiDirectory)) {
      if (psiClass.isInstance(parent)) {
        return (T) parent;
      }
      parent = parent.getParent();
    }
    return null;
  }

  @Nullable
  public static <T extends PsiElement> T findFirstChildOfClassRecursive(PsiElement parent, Class<T> psiClass) {
    List<T> holder = Lists.newArrayListWithExpectedSize(1);
    Processor<T> getFirst = t -> {
      holder.add(t);
      return false;
    };
    processChildrenOfType(parent, getFirst, psiClass);
    return holder.isEmpty() ? null : holder.get(0);
  }

  @Nullable
  public static <T extends PsiElement> T findLastChildOfClassRecursive(PsiElement parent, Class<T> psiClass) {
    List<T> holder = Lists.newArrayListWithExpectedSize(1);
    Processor<T> getFirst = t -> {
      holder.add(t);
      return false;
    };
    processChildrenOfType(parent, getFirst, psiClass, true);
    return holder.isEmpty() ? null : holder.get(0);
  }

  public static <T extends PsiElement> List<T> findAllChildrenOfClassRecursive(PsiElement parent, Class<T> psiClass) {
    List<T> result = Lists.newArrayList();
    processChildrenOfType(parent, new CommonProcessors.CollectProcessor(result), psiClass);
    return result;
  }

  /**
   * Walk through entire PSI tree rooted at 'element', processing all children of the given type.
   * @return true if processing was stopped by the processor
   */
  public static <T extends PsiElement> boolean processChildrenOfType(
    PsiElement element,
    Processor<T> processor,
    Class<T> psiClass) {
    return processChildrenOfType(element, processor, psiClass, false);
  }

  /**
   * Walk through entire PSI tree rooted at 'element', processing all children of the given type.
   * @return true if processing was stopped by the processor
   */
  private static <T extends PsiElement> boolean processChildrenOfType(
    PsiElement element,
    Processor<T> processor,
    Class<T> psiClass,
    boolean reverseOrder) {
    PsiElement child = reverseOrder ? element.getLastChild() : element.getFirstChild();
    while (child != null) {
      if (psiClass.isInstance(child)) {
        if (!processor.process((T) child)) {
          return true;
        }
      }
      if (processChildrenOfType(child, processor, psiClass, reverseOrder)) {
        return true;
      }
      child = reverseOrder ? child.getPrevSibling() : child.getNextSibling();
    }
    return false;
  }

  public static TextRange childRangeInParent(TextRange parentRange, TextRange childRange) {
    return childRange.shiftRight(-parentRange.getStartOffset());
  }

  @Nullable
  public static String getFilePath(@Nullable PsiFile file) {
    VirtualFile virtualFile = file != null ? file.getVirtualFile() : null;
    return virtualFile != null ? virtualFile.getPath() : null;
  }

  /**
   * For ReferenceExpressions, follows the chain of references until it hits a non-ReferenceExpression.
   * For other types, returns the input expression.
   */
  public static PsiElement getReferencedTarget(Expression expr) {
    PsiElement element = expr;
    while (element instanceof ReferenceExpression) {
      PsiElement referencedElement = ((ReferenceExpression) element).getReferencedElement();
      if (referencedElement == null) {
        return element;
      }
      element = referencedElement;
    }
    return element;
  }

  /**
   * For ReferenceExpressions, follows the chain of references until it hits a non-ReferenceExpression, then
   * evaluates the value of that target.
   * For other types, returns the input expression.
   */
  public static PsiElement getReferencedTargetValue(Expression expr) {
    PsiElement element = getReferencedTarget(expr);
    if (element instanceof TargetExpression) {
      PsiElement parent = element.getParent();
      if (parent instanceof AssignmentStatement) {
        return ((AssignmentStatement) parent).getAssignedValue();
      }
    }
    return element;
  }

}
