// Copyright 2015 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.rules.java;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Collection;
import java.util.Map;

/** A Provider describing the java sources directly belonging to a java rule. */
@Immutable
@AutoCodec
public final class JavaSourceInfoProvider implements TransitiveInfoProvider {
  private final Collection<Artifact> sourceFiles;
  private final Collection<Artifact> sourceJars;
  private final Collection<Artifact> jarFiles;
  private final Collection<Artifact> sourceJarsForJarFiles;
  private final Map<PathFragment, Artifact> resources;

  @VisibleForSerialization
  JavaSourceInfoProvider(
      Collection<Artifact> sourceFiles,
      Collection<Artifact> sourceJars,
      Collection<Artifact> jarFiles,
      Collection<Artifact> sourceJarsForJarFiles,
      Map<PathFragment, Artifact> resources) {
    this.sourceFiles = sourceFiles;
    this.sourceJars = sourceJars;
    this.jarFiles = jarFiles;
    this.sourceJarsForJarFiles = sourceJarsForJarFiles;
    this.resources = resources;
  }

  /** Gets the original Java source files provided as inputs to this rule. */
  public Collection<Artifact> getSourceFiles() {
    return sourceFiles;
  }

  /**
   * Gets the original source jars provided as inputs to this rule.
   *
   * <p>These should contain Java source files, but can contain other files as well.
   */
  public Collection<Artifact> getSourceJars() {
    return sourceJars;
  }

  /**
   * Gets the original pre-built jars provided as inputs to this rule.
   *
   * <p>These should be used where .class files are needed or wanted in place of recompiling the
   * sources from {@link #getSourceJarsForJarFiles()}, as this is the source of truth used by the
   * normal Java machinery.
   */
  public Collection<Artifact> getJarFiles() {
    return jarFiles;
  }

  /**
   * Gets the source jars containing the sources of the jars contained in {@link #getJarFiles}.
   *
   * <p>These should be used in place of {@link #getJarFiles()} if and only if source is required.
   */
  public Collection<Artifact> getSourceJarsForJarFiles() {
    return sourceJarsForJarFiles;
  }

  /**
   * Gets the Java resources which were included in this rule's output.
   *
   * <p>Each key in the map (a path within the jar) should correspond to the artifact which belongs
   * at that path. The path fragment should be some suffix of the artifact's exec path.
   */
  public Map<PathFragment, Artifact> getResources() {
    return resources;
  }

  /**
   * Constructs a JavaSourceInfoProvider using the sources in the given JavaTargetAttributes.
   *
   * @param attributes the object from which to draw the sources
   * @param semantics semantics used to find the path for a resource within the jar
   */
  public static JavaSourceInfoProvider fromJavaTargetAttributes(
      JavaTargetAttributes attributes, JavaSemantics semantics) {
    return new Builder()
        .setSourceFiles(attributes.getSourceFiles())
        .setSourceJars(attributes.getSourceJars())
        .setResources(attributes.getResources())
        .build();
  }

  public static JavaSourceInfoProvider merge(Collection<JavaSourceInfoProvider> sourceInfos) {
    JavaSourceInfoProvider.Builder javaSourceInfo = new JavaSourceInfoProvider.Builder();
    ImmutableList.Builder<Artifact> jarFiles = new ImmutableList.Builder<>();
    ImmutableMap.Builder<PathFragment, Artifact> resources = new ImmutableMap.Builder<>();
    ImmutableList.Builder<Artifact> sourceFiles = new ImmutableList.Builder<>();
    ImmutableList.Builder<Artifact> sourceJars = new ImmutableList.Builder<>();
    ImmutableList.Builder<Artifact> sourceJarsForJarFiles = new ImmutableList.Builder<>();

    for (JavaSourceInfoProvider sourceInfo : sourceInfos) {
      jarFiles.addAll(sourceInfo.getJarFiles());
      resources.putAll(sourceInfo.getResources());
      sourceFiles.addAll(sourceInfo.getSourceFiles());
      sourceJars.addAll(sourceInfo.getSourceJars());
      sourceJarsForJarFiles.addAll(sourceInfo.getSourceJarsForJarFiles());
    }
    javaSourceInfo.setJarFiles(jarFiles.build());
    javaSourceInfo.setResources(resources.build());
    javaSourceInfo.setSourceFiles(sourceFiles.build());
    javaSourceInfo.setSourceJars(sourceJars.build());
    javaSourceInfo.setSourceJarsForJarFiles(sourceJarsForJarFiles.build());
    return javaSourceInfo.build();
  }

  /** Builder class for constructing JavaSourceInfoProviders. */
  public static final class Builder {
    private Collection<Artifact> sourceFiles = ImmutableList.<Artifact>of();
    private Collection<Artifact> sourceJars = ImmutableList.<Artifact>of();
    private Collection<Artifact> jarFiles = ImmutableList.<Artifact>of();
    private Collection<Artifact> sourceJarsForJarFiles = ImmutableList.<Artifact>of();
    private Map<PathFragment, Artifact> resources = ImmutableMap.<PathFragment, Artifact>of();

    /** Sets the source files included as part of the sources of this rule. */
    public Builder setSourceFiles(Collection<Artifact> sourceFiles) {
      this.sourceFiles = Preconditions.checkNotNull(sourceFiles);
      return this;
    }

    /** Sets the source jars included as part of the sources of this rule. */
    public Builder setSourceJars(Collection<Artifact> sourceJars) {
      this.sourceJars = Preconditions.checkNotNull(sourceJars);
      return this;
    }

    /** Sets the pre-built jar files included as part of the sources of this rule. */
    public Builder setJarFiles(Collection<Artifact> jarFiles) {
      this.jarFiles = Preconditions.checkNotNull(jarFiles);
      return this;
    }

    /**
     * Sets the source jars corresponding to the jar files included in this rule.
     *
     * <p>Used by, e.g., the srcjars attribute of {@link JavaImport}.
     */
    public Builder setSourceJarsForJarFiles(Collection<Artifact> sourceJarsForJarFiles) {
      this.sourceJarsForJarFiles = Preconditions.checkNotNull(sourceJarsForJarFiles);
      return this;
    }

    /**
     * Sets the resources included in this rule.
     *
     * <p>Each key in the map (a path within the jar) should correspond to the artifact which
     * belongs at that path. The path fragment should be some tail of the artifact's exec path.
     */
    public Builder setResources(Map<PathFragment, Artifact> resources) {
      this.resources = Preconditions.checkNotNull(resources);
      return this;
    }

    /** Constructs the JavaSourceInfoProvider from the provided Java sources. */
    public JavaSourceInfoProvider build() {
      return new JavaSourceInfoProvider(
          sourceFiles, sourceJars, jarFiles, sourceJarsForJarFiles, resources);
    }
  }
}
