/*
 * 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.ParenthesizedExpression;
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 java.util.List;
import javax.annotation.Nullable;

/** 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.<br>
   * Unwraps ParenthesizedExpression.<br>
   * For other types, returns the input expression.
   */
  public static PsiElement getReferencedTarget(Expression expr) {
    PsiElement element = expr;
    while (true) {
      PsiElement unwrapped = unwrap(element);
      if (unwrapped == null || unwrapped == element) {
        return element;
      }
      element = unwrapped;
    }
  }

  private static PsiElement unwrap(PsiElement expr) {
    if (expr instanceof ParenthesizedExpression) {
      return ((ParenthesizedExpression) expr).getContainedExpression();
    }
    if (expr instanceof ReferenceExpression) {
      return ((ReferenceExpression) expr).getReferencedElement();
    }
    return expr;
  }

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