/*
 * 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.Label;
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.annotation.Nullable;
import javax.swing.Icon;

/** 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) {
    if (basePackage == null) {
      return null;
    }
    Label packageLabel = basePackage.getPackageLabel();
    if (packageLabel == null) {
      return null;
    }
    String basePackagePath = packageLabel.blazePackage().relativePath();
    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;
  }
}
