// Copyright 2018 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.devtools.build.lib.analysis;

import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.cmdline.Label;
import java.util.HashSet;
import java.util.Set;

/**
 * Morally a {@link SetMultimap} from artifacts to the labels that own them, which may not be just
 * {@link Artifact#getOwnerLabel} depending on the build. Optimizes for artifacts that are owned by
 * their {@link Artifact#getOwnerLabel} by storing them separately.
 */
public class ArtifactsToOwnerLabels {
  private final SetMultimap<Artifact, Label> artifactToMultipleOrDifferentOwnerLabels;
  private final Set<Artifact> artifactsOwnedOnlyByTheirLabels;

  private ArtifactsToOwnerLabels(
      SetMultimap<Artifact, Label> artifactToMultipleOrDifferentOwnerLabels,
      Set<Artifact> artifactsOwnedOnlyByTheirLabels) {
    this.artifactToMultipleOrDifferentOwnerLabels = artifactToMultipleOrDifferentOwnerLabels;
    this.artifactsOwnedOnlyByTheirLabels = artifactsOwnedOnlyByTheirLabels;
  }

  public Set<Label> getOwners(Artifact artifact) {
    if (artifactsOwnedOnlyByTheirLabels.contains(artifact)) {
      Preconditions.checkState(
          !artifactToMultipleOrDifferentOwnerLabels.containsKey(artifact),
          "Artifact %s incorrectly in multiple categories",
          artifact);
      Label ownerLabel = artifact.getOwnerLabel();
      if (ownerLabel == null) {
        return ImmutableSet.of();
      }
      return ImmutableSet.of(ownerLabel);
    }
    return Preconditions.checkNotNull(
        artifactToMultipleOrDifferentOwnerLabels.get(artifact), artifact);
  }

  public Set<Artifact> getArtifacts() {
    return Sets.union(
        artifactsOwnedOnlyByTheirLabels, artifactToMultipleOrDifferentOwnerLabels.keySet());
  }

  public Builder toBuilder() {
    return new Builder(
        HashMultimap.create(artifactToMultipleOrDifferentOwnerLabels),
        new HashSet<>(artifactsOwnedOnlyByTheirLabels));
  }

  static class Builder {
    private final SetMultimap<Artifact, Label> artifactToMultipleOrDifferentOwnerLabels;
    private final Set<Artifact> artifactsOwnedOnlyByTheirLabels;

    Builder() {
      this(HashMultimap.create(), new HashSet<>());
    }

    private Builder(
        SetMultimap<Artifact, Label> artifactToMultipleOrDifferentOwnerLabels,
        Set<Artifact> artifactsOwnedOnlyByTheirLabels) {
      this.artifactToMultipleOrDifferentOwnerLabels = artifactToMultipleOrDifferentOwnerLabels;
      this.artifactsOwnedOnlyByTheirLabels = artifactsOwnedOnlyByTheirLabels;
    }

    public Builder addArtifact(Artifact artifact) {
      if (artifactToMultipleOrDifferentOwnerLabels.containsKey(artifact)) {
        Label ownerLabel = artifact.getOwnerLabel();
        if (ownerLabel != null) {
          artifactToMultipleOrDifferentOwnerLabels.put(artifact, artifact.getOwnerLabel());
        }
      } else {
        artifactsOwnedOnlyByTheirLabels.add(artifact);
      }
      return this;
    }

    public Builder addArtifact(Artifact artifact, Label label) {
      Preconditions.checkNotNull(label, artifact);
      if (label.equals(artifact.getOwnerLabel())) {
        addArtifact(artifact);
      } else {
        artifactToMultipleOrDifferentOwnerLabels.put(artifact, label);
        if (artifactsOwnedOnlyByTheirLabels.remove(artifact)) {
          // Redoing this call now that we have a mismatched label will force addition into the
          // multimap.
          addArtifact(artifact);
        }
      }
      return this;
    }

    ArtifactsToOwnerLabels build() {
      return new ArtifactsToOwnerLabels(
          artifactToMultipleOrDifferentOwnerLabels, artifactsOwnedOnlyByTheirLabels);
    }
  }
}
