/*
 * 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.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.lang.buildfile.globbing.UnixGlob;
import com.google.idea.blaze.base.lang.buildfile.psi.*;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.PsiPolyVariantCachingReference;
import com.intellij.util.IncorrectOperationException;

import java.io.File;
import java.util.List;
import java.util.function.Predicate;

/**
 * References from a glob to a list of files contained in the same blaze package.
 */
public class GlobReference extends PsiPolyVariantCachingReference {

  private static final Logger LOG = Logger.getInstance(GlobReference.class);

  private final GlobExpression element;

  public GlobReference(GlobExpression element) {
    this.element = element;
  }

  /**
   * Returns true iff the complete, resolved glob references the specified file.<p>
   * In particular, it's not concerned with individual patterns referencing
   * the file, only whether the overall glob does
   * (i.e. returns false if the file is explicitly excluded).
   */
  public boolean matches(String packageRelativePath, boolean isDirectory) {
    if (isDirectory && element.areDirectoriesExcluded()) {
      return false;
    }
    for (String exclude : resolveListContents(element.getExcludes())) {
      if (UnixGlob.matches(exclude, packageRelativePath)) {
        return false;
      }
    }
    for (String include : resolveListContents(element.getIncludes())) {
      if (UnixGlob.matches(include, packageRelativePath)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns true iff an include pattern *without wildcards* matches the given path and
   * it's not excluded.
   */
  public boolean matchesDirectly(String packageRelativePath, boolean isDirectory) {
    if (isDirectory && element.areDirectoriesExcluded()) {
      return false;
    }
    for (String exclude : resolveListContents(element.getExcludes())) {
      if (UnixGlob.matches(exclude, packageRelativePath)) {
        return false;
      }
    }
    for (String include : resolveListContents(element.getIncludes())) {
      if (!hasWildcard(include) && UnixGlob.matches(include, packageRelativePath)) {
        return true;
      }
    }
    return false;
  }

  private static boolean hasWildcard(String pattern) {
    return pattern.contains("*");
  }

  @Override
  protected ResolveResult[] resolveInner(boolean incompleteCode, PsiFile containingFile) {
    File containingDirectory = ((BuildFile) containingFile).getFile().getParentFile();
    if (containingDirectory == null) {
      return ResolveResult.EMPTY_ARRAY;
    }
    List<String> includes = resolveListContents(element.getIncludes());
    List<String> excludes = resolveListContents(element.getExcludes());
    boolean directoriesExcluded = element.areDirectoriesExcluded();
    if (includes.isEmpty()) {
      return ResolveResult.EMPTY_ARRAY;
    }

    try {
      List<File> files = UnixGlob.forPath(containingDirectory)
        .addPatterns(includes)
        .addExcludes(excludes)
        .setExcludeDirectories(directoriesExcluded)
        .setDirectoryFilter(directoryFilter(containingDirectory.getPath()))
        .glob();
      List<ResolveResult> results = Lists.newArrayListWithCapacity(files.size());
      for (File file : files) {
        PsiFileSystemItem psiFile = BuildReferenceManager.getInstance(element.getProject()).resolveFile(file);
        if (psiFile != null) {
          results.add(new PsiElementResolveResult(psiFile));
        }
      }
      return results.toArray(ResolveResult.EMPTY_ARRAY);

    } catch (Exception e) {
      return ResolveResult.EMPTY_ARRAY;
    }
  }

  private static Predicate<File> directoryFilter(String base) {
    return file -> {
      if (base.equals(file.getPath())) {
        return true;
      }
      File child = new File(file, "BUILD");
      FileAttributeProvider attributeProvider = FileAttributeProvider.getInstance();
      return !attributeProvider.exists(child) || attributeProvider.isDirectory(child);
    };
  }

  private static List<String> resolveListContents(Expression expr) {
    if (expr == null) {
      return ImmutableList.of();
    }
    PsiElement rootElement = PsiUtils.getReferencedTargetValue(expr);
    if (!(rootElement instanceof ListLiteral)) {
      return ImmutableList.of();
    }
    Expression[] children = ((ListLiteral) rootElement).getElements();
    List<String> strings = Lists.newArrayListWithCapacity(children.length);
    for (Expression child : children) {
      if (child instanceof StringLiteral) {
        strings.add(((StringLiteral) child).getStringContents());
      }
    }
    return strings;
  }

  @Override
  public GlobExpression getElement() {
    return element;
  }

  @Override
  public TextRange getRangeInElement() {
    return element.getReferenceTextRange();
  }

  @Override
  public boolean isSoft() {
    return true;
  }

  @Override
  public Object[] getVariants() {
    return EMPTY_ARRAY;
  }

  @Override
  public String getCanonicalText() {
    return getValue();
  }

  @Override
  public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
    return element;
  }

  @Override
  public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException {
    return this.element;
  }

  public String getValue() {
    String text = element.getText();
    final TextRange range = getRangeInElement();
    try {
      return range.substring(text);
    }
    catch (StringIndexOutOfBoundsException e) {
      LOG.error("Wrong range in reference " + this + ": " + range + ". Reference text: '" + text + "'", e);
      return text;
    }
  }

}
