/*
 * 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.
 *
 * The working set is:
 *   - All new untracked directories (git only)
 *   - All modified BUILD files
 *   - All modified java files
 *
 * 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
 *
 * 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);
  }
}
