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

import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.sync.workspace.WorkingSet;
import java.util.Set;

/**
 * Computes the working set of files of directories from source control.
 *
 * <p>The working set is: - All new untracked directories (git only) - All modified BUILD files -
 * All modified java files
 *
 * <p>A rule is considered part of the working set if any of the following is true: - Its BUILD file
 * is modified - Its BUILD file is under a new directory - Any of its java files are modified - Any
 * of its java files are under a new directory
 *
 * <p>Rules in the working set get an expanded classpath of their direct deps, i.e. they temporarily
 * defeat classpath reduction.
 */
public class JavaWorkingSet {
  private final Set<String> modifiedBuildFileRelativePaths;
  private final Set<String> modifiedJavaFileRelativePaths;

  public JavaWorkingSet(WorkspaceRoot workspaceRoot, WorkingSet workingSet) {
    Set<String> modifiedBuildFileRelativePaths = Sets.newHashSet();
    Set<String> modifiedJavaFileRelativePaths = Sets.newHashSet();

    for (WorkspacePath workspacePath :
        Iterables.concat(workingSet.addedFiles, workingSet.modifiedFiles)) {
      if (workspaceRoot.fileForPath(workspacePath).getName().equals("BUILD")) {
        modifiedBuildFileRelativePaths.add(workspacePath.relativePath());
      } else if (workspacePath.relativePath().endsWith(".java")) {
        modifiedJavaFileRelativePaths.add(workspacePath.relativePath());
      }
    }

    this.modifiedBuildFileRelativePaths = modifiedBuildFileRelativePaths;
    this.modifiedJavaFileRelativePaths = modifiedJavaFileRelativePaths;
  }

  public boolean isRuleInWorkingSet(RuleIdeInfo ruleIdeInfo) {
    ArtifactLocation buildFile = ruleIdeInfo.buildFile;
    if (buildFile != null) {
      if (modifiedBuildFileRelativePaths.contains(buildFile.getRelativePath())) {
        return true;
      }
    }

    for (ArtifactLocation artifactLocation : ruleIdeInfo.sources) {
      if (isInWorkingSet(artifactLocation)) {
        return true;
      }
    }
    return false;
  }

  public boolean isInWorkingSet(ArtifactLocation artifactLocation) {
    return isInWorkingSet(artifactLocation.getRelativePath());
  }

  boolean isInWorkingSet(String relativePath) {
    return modifiedJavaFileRelativePaths.contains(relativePath);
  }
}
