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

import com.google.idea.blaze.base.lang.buildfile.completion.FilePathLookupElement;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
import com.google.idea.blaze.base.lang.buildfile.search.BlazePackage;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NullableLazyValue;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.PathUtil;
import com.intellij.util.PlatformIcons;
import icons.BlazeIcons;
import javax.swing.Icon;
import org.jetbrains.annotations.Nullable;

/** The data relevant to finding file lookups. */
public class FileLookupData {

  /** The type of path string format */
  public enum PathFormat {
    /** BUILD label without a leading '//', which can only reference targets in the same package. */
    PackageLocal,
    /** a BUILD label with leading '//', which can reference targets in other packages. */
    NonLocal,
    /** a path string which can reference any files, and has no leading '//'. */
    NonLocalWithoutInitialBackslashes
  }

  @Nullable
  public static FileLookupData nonLocalFileLookup(String originalLabel, StringLiteral element) {
    return nonLocalFileLookup(
        originalLabel, element.getContainingFile(), element.getQuoteType(), PathFormat.NonLocal);
  }

  @Nullable
  public static FileLookupData nonLocalFileLookup(
      String originalLabel,
      @Nullable BuildFile containingFile,
      QuoteType quoteType,
      PathFormat pathFormat) {
    if (originalLabel.indexOf(':') != -1) {
      // it's a package-local reference
      return null;
    }
    // handle the single '/' case by calling twice.
    String relativePath = StringUtil.trimStart(StringUtil.trimStart(originalLabel, "/"), "/");
    if (relativePath.startsWith("/")) {
      return null;
    }
    return new FileLookupData(
        originalLabel, containingFile, null, relativePath, pathFormat, quoteType, null);
  }

  @Nullable
  public static FileLookupData packageLocalFileLookup(String originalLabel, StringLiteral element) {
    if (originalLabel.startsWith("/")) {
      return null;
    }
    BlazePackage blazePackage = element.getBlazePackage();
    BuildFile baseBuildFile = blazePackage != null ? blazePackage.buildFile : null;
    return packageLocalFileLookup(originalLabel, element, baseBuildFile, null);
  }

  @Nullable
  public static FileLookupData packageLocalFileLookup(
      String originalLabel,
      StringLiteral element,
      @Nullable BuildFile basePackage,
      @Nullable VirtualFileFilter fileFilter) {
    String basePackagePath =
        basePackage != null ? basePackage.getWorkspaceRelativePackagePath() : null;
    if (basePackagePath == null) {
      return null;
    }
    String filePath = basePackagePath + "/" + LabelUtils.getRuleComponent(originalLabel);
    return new FileLookupData(
        originalLabel,
        basePackage,
        basePackagePath,
        filePath,
        PathFormat.PackageLocal,
        element.getQuoteType(),
        fileFilter);
  }

  private final String originalLabel;
  private final BuildFile containingFile;
  @Nullable private final String containingPackage;
  public final String filePathFragment;
  public final PathFormat pathFormat;
  private final QuoteType quoteType;
  @Nullable private final VirtualFileFilter fileFilter;

  private FileLookupData(
      String originalLabel,
      @Nullable BuildFile containingFile,
      @Nullable String containingPackage,
      String filePathFragment,
      PathFormat pathFormat,
      QuoteType quoteType,
      @Nullable VirtualFileFilter fileFilter) {

    this.originalLabel = originalLabel;
    this.containingFile = containingFile;
    this.containingPackage = containingPackage;
    this.fileFilter = fileFilter;
    this.filePathFragment = filePathFragment;
    this.pathFormat = pathFormat;
    this.quoteType = quoteType;

    assert (pathFormat != PathFormat.PackageLocal
        || (containingPackage != null && containingFile != null));
  }

  public boolean acceptFile(Project project, VirtualFile file) {
    if (fileFilter != null && !fileFilter.accept(file)) {
      return false;
    }
    if (pathFormat != PathFormat.PackageLocal) {
      return file.isDirectory();
    }
    if (file.equals(containingFile.getOriginalFile().getVirtualFile())) {
      return false;
    }
    boolean blazePackage =
        Blaze.getBuildSystemProvider(project).findBuildFileInDirectory(file) != null;
    return !blazePackage;
  }

  public FilePathLookupElement lookupElementForFile(
      Project project, VirtualFile file, @Nullable WorkspacePath workspacePath) {
    NullableLazyValue<Icon> icon =
        new NullableLazyValue<Icon>() {
          @Override
          protected Icon compute() {
            if (file.findChild("BUILD") != null) {
              return BlazeIcons.BuildFile;
            }
            if (file.isDirectory()) {
              return PlatformIcons.FOLDER_ICON;
            }
            PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
            return psiFile != null ? psiFile.getIcon(0) : AllIcons.FileTypes.Any_type;
          }
        };
    String fullLabel =
        workspacePath != null ? getFullLabel(workspacePath.relativePath()) : file.getPath();
    String itemText = workspacePath != null ? getItemText(workspacePath.relativePath()) : fullLabel;
    return new FilePathLookupElement(fullLabel, itemText, quoteType, icon);
  }

  private String getFullLabel(String relativePath) {
    if (pathFormat != PathFormat.PackageLocal) {
      if (pathFormat == PathFormat.NonLocal) {
        relativePath = "//" + relativePath;
      }
      return relativePath;
    }
    String prefix;
    int colonIndex = originalLabel.indexOf(':');
    if (originalLabel.startsWith("/")) {
      prefix = colonIndex == -1 ? originalLabel + ":" : originalLabel.substring(0, colonIndex + 1);
    } else {
      prefix = originalLabel.substring(0, colonIndex + 1);
    }
    return prefix + getItemText(relativePath);
  }

  private String getItemText(String relativePath) {
    if (pathFormat == PathFormat.PackageLocal) {
      if (containingPackage.length() > relativePath.length()) {
        return "";
      }
      return StringUtil.trimStart(relativePath.substring(containingPackage.length()), "/");
    }
    String parentPath = PathUtil.getParentPath(relativePath);
    while (!parentPath.isEmpty()) {
      if (filePathFragment.startsWith(parentPath + "/")) {
        return StringUtil.trimStart(relativePath, parentPath + "/");
      } else if (filePathFragment.startsWith(parentPath)) {
        return StringUtil.trimStart(relativePath, parentPath);
      }
      parentPath = PathUtil.getParentPath(parentPath);
    }
    return relativePath;
  }
}
