/*
 * 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.java.lang.build;

import com.google.idea.blaze.base.lang.buildfile.references.GlobReference;
import com.google.idea.blaze.base.lang.buildfile.search.BlazePackage;
import com.google.idea.blaze.base.lang.buildfile.search.ResolveUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor;
import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo;
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * Removes glob references which don't refer directly to the item(s) being deleted (b/28979434)
 * (e.g. indirect references from glob([*.java])).<p>
 *
 * Runs before JavaSafeDeleteProcessor, and delegates to it, removing indirect glob references.
 * Only the first valid SafeDeleteProcessorDelegate is used in almost all cases*, so this class effectively
 * replaces JavaSafeDeleteProcessor (*in the situations where all processors are used, this class has no effect).
 */
public class BuildFileSafeDeleteProcessor extends JavaSafeDeleteProcessor {

  /**
   * Delegates to JavaSafeDeleteProcessor, then removes indirect glob references which we don't want to block safe delete.
   */
  @Nullable
  @Override
  public NonCodeUsageSearchInfo findUsages(@NotNull PsiElement element,
                                           @NotNull PsiElement[] allElementsToDelete,
                                           @NotNull List<UsageInfo> result) {
    NonCodeUsageSearchInfo superResult = super.findUsages(element, allElementsToDelete, result);
    Iterator<UsageInfo> iter = result.iterator();
    while (iter.hasNext()) {
      if (ignoreUsage(iter.next())) {
        iter.remove();
      }
    }
    return superResult;
  }

  /**
   * We keep globs which reference the file directly (i.e. without wildcards), and remove all
   * indirect references for the purposes of the 'safe delete' action.
   */
  private static boolean ignoreUsage(UsageInfo usage) {
    if (usage.getReference() instanceof GlobReference && usage instanceof SafeDeleteUsageInfo) {
      PsiElement referencedElement = ((SafeDeleteUsageInfo) usage).getReferencedElement();
      PsiFileSystemItem file = ResolveUtil.asFileSystemItemSearch(referencedElement);
      String relativePath = getBlazePackageRelativePathToFile(file);
      if (relativePath == null) {
        return false;
      }
      return !((GlobReference) usage.getReference()).matchesDirectly(relativePath, file.isDirectory());
    }
    return false;
  }

  @Nullable
  private static String getBlazePackageRelativePathToFile(@Nullable PsiFileSystemItem file) {
    if (file == null) {
      return null;
    }
    BlazePackage containingPackage = BlazePackage.getContainingPackage(file);
    if (containingPackage == null) {
      return null;
    }
    return containingPackage.getRelativePathToChild(file.getVirtualFile());
  }

  @Override
  public boolean handlesElement(PsiElement element) {
    return super.handlesElement(element);
  }

  @Nullable
  @Override
  public Collection<? extends PsiElement> getElementsToSearch(@NotNull PsiElement element,
                                                              @Nullable Module module,
                                                              @NotNull Collection<PsiElement> allElementsToDelete) {
    return super.getElementsToSearch(element, module, allElementsToDelete);
  }

  @Nullable
  @Override
  public Collection<PsiElement> getAdditionalElementsToDelete(@NotNull PsiElement element,
                                                              @NotNull Collection<PsiElement> allElementsToDelete,
                                                              boolean askUser) {
    return super.getAdditionalElementsToDelete(element, allElementsToDelete, askUser);
  }

  @Nullable
  @Override
  public Collection<String> findConflicts(@NotNull PsiElement element, @NotNull PsiElement[] allElementsToDelete) {
    return super.findConflicts(element, allElementsToDelete);
  }

  @Nullable
  @Override
  public UsageInfo[] preprocessUsages(Project project, UsageInfo[] usages) {
    return usages;
  }

  @Override
  public void prepareForDeletion(PsiElement element) throws IncorrectOperationException {
  }

  @Override
  public boolean isToSearchInComments(PsiElement element) {
    return super.isToSearchInComments(element);
  }

  @Override
  public void setToSearchInComments(PsiElement element, boolean enabled) {
    super.setToSearchInComments(element, enabled);
  }

  @Override
  public boolean isToSearchForTextOccurrences(PsiElement element) {
    return super.isToSearchForTextOccurrences(element);
  }

  @Override
  public void setToSearchForTextOccurrences(PsiElement element, boolean enabled) {
    super.setToSearchForTextOccurrences(element, enabled);
  }
}
