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

import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.history.core.Paths;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PackagePrefixFileSystemItem;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.PathUtil;
import com.intellij.util.Processor;
import java.util.Objects;
import javax.annotation.Nullable;

/** Defines the files accessible by a given blaze package. */
public class BlazePackage {

  @Nullable
  public static BlazePackage getContainingPackage(PsiFileSystemItem file) {
    if (file instanceof PsiFile) {
      file = ((PsiFile) file).getOriginalFile();
    }
    if (file instanceof BuildFile
        && Blaze.getBuildSystemProvider(file.getProject()).isBuildFile(file.getName())) {
      return new BlazePackage((BuildFile) file);
    }
    return getContainingPackage(getPsiDirectory(file));
  }

  @Nullable
  private static PsiDirectory getPsiDirectory(PsiFileSystemItem file) {
    if (file instanceof PsiDirectory) {
      return (PsiDirectory) file;
    }
    if (file instanceof PsiFile) {
      return ((PsiFile) file).getContainingDirectory();
    }
    if (file instanceof PackagePrefixFileSystemItem) {
      return ((PackagePrefixFileSystemItem) file).getDirectory();
    }
    return null;
  }

  @Nullable
  public static BlazePackage getContainingPackage(@Nullable PsiDirectory dir) {
    while (dir != null) {
      VirtualFile buildFile =
          Blaze.getBuildSystemProvider(dir.getProject())
              .findBuildFileInDirectory(dir.getVirtualFile());
      if (buildFile != null) {
        PsiFile psiFile = dir.getManager().findFile(buildFile);
        if (psiFile != null) {
          return psiFile instanceof BuildFile ? new BlazePackage((BuildFile) psiFile) : null;
        }
      }
      dir = dir.getParentDirectory();
    }
    return null;
  }

  public final BuildFile buildFile;

  private BlazePackage(BuildFile buildFile) {
    this.buildFile = buildFile;
  }

  @Nullable
  public PsiDirectory getContainingDirectory() {
    return buildFile.getParent();
  }

  /**
   * The search scope corresponding to this package (i.e. not crossing package boundaries).
   *
   * @param onlyBlazeFiles if true, the scope is limited to BUILD and Skylark files.
   */
  public GlobalSearchScope getSearchScope(boolean onlyBlazeFiles) {
    return new BlazePackageSearchScope(this, onlyBlazeFiles);
  }

  /**
   * Returns the file path relative to this blaze package, or null if it does lie inside this
   * package
   */
  @Nullable
  public String getPackageRelativePath(String filePath) {
    String packageFilePath = PathUtil.getParentPath(buildFile.getFilePath());
    return Paths.relativeIfUnder(filePath, packageFilePath);
  }

  /** Formats the child file path as a BUILD label (i.e. "//package_path[:relative_path]") */
  @Nullable
  public String getBuildLabelForChild(String filePath) {
    WorkspacePath packagePath = buildFile.getPackageWorkspacePath();
    if (packagePath == null) {
      return null;
    }
    String relativePath = getPackageRelativePath(filePath);
    if (relativePath == null) {
      return null;
    }
    if (relativePath.isEmpty()) {
      return "//" + packagePath;
    }
    return "//" + packagePath + ":" + relativePath;
  }

  /**
   * The path from the blaze package directory to the child file, or null if the package directory
   * is not an ancestor of the provided file.
   */
  @Nullable
  public String getRelativePathToChild(@Nullable VirtualFile child) {
    if (child == null) {
      return null;
    }
    String packagePath = PathUtil.getParentPath(buildFile.getFilePath());
    return Paths.relativeIfUnder(child.getPath(), packagePath);
  }

  /**
   * Walks the directory tree, processing all files accessible by this package (i.e. not processing
   * child packages).
   */
  public void processPackageFiles(Processor<PsiFile> processor) {
    PsiDirectory dir = getContainingDirectory();
    if (dir == null) {
      return;
    }
    processPackageFiles(processor, dir);
  }

  private static void processPackageFiles(Processor<PsiFile> processor, PsiDirectory directory) {
    processDirectory(processor, directory);
    for (PsiDirectory child : directory.getSubdirectories()) {
      if (!isBlazePackage(child)) {
        processPackageFiles(processor, directory);
      }
    }
  }

  private static boolean isBlazePackage(PsiDirectory dir) {
    return Blaze.getBuildSystemProvider(dir.getProject())
            .findBuildFileInDirectory(dir.getVirtualFile())
        != null;
  }

  private static void processDirectory(Processor<PsiFile> processor, PsiDirectory directory) {
    for (PsiFile file : directory.getFiles()) {
      processor.process(file);
    }
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof BlazePackage)) {
      return false;
    }
    if (obj == this) {
      return true;
    }
    BlazePackage that = (BlazePackage) obj;
    return Objects.equals(buildFile.getFilePath(), that.buildFile.getFilePath());
  }

  @Override
  public int hashCode() {
    return Objects.hash(buildFile.getFilePath());
  }

  @Override
  public String toString() {
    return String.format(
        "%s package: %s",
        Blaze.buildSystemName(buildFile.getProject()), buildFile.getPackageWorkspacePath());
  }

  public static boolean hasBlazePackageChild(PsiDirectory directory) {
    ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(directory.getProject());
    BuildSystemProvider buildSystemProvider = Blaze.getBuildSystemProvider(directory.getProject());
    return hasBlazePackageChild(index, buildSystemProvider, directory);
  }

  private static boolean hasBlazePackageChild(
      ProjectFileIndex index, BuildSystemProvider buildSystemProvider, PsiDirectory directory) {
    if (!index.isInSourceContent(directory.getVirtualFile())) {
      // only search project files
      return false;
    }
    if (buildSystemProvider.findBuildFileInDirectory(directory.getVirtualFile()) != null) {
      return true;
    }
    for (PsiDirectory child : directory.getSubdirectories()) {
      if (hasBlazePackageChild(index, buildSystemProvider, child)) {
        return true;
      }
    }
    return false;
  }
}
