// Copyright 2017 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 static com.google.common.base.Preconditions.checkNotNull;

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.actions.ParamFileInfo;
import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.List;
import java.util.Map;

/** Builds the action to package the resources for a Java rule into a jar. */
public class ResourceJarActionBuilder {
  public static final String MNEMONIC = "JavaResourceJar";

  private static final ParamFileInfo PARAM_FILE_INFO =
      ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).build();

  private Artifact outputJar;
  private Map<PathFragment, Artifact> resources = ImmutableMap.of();
  private NestedSet<Artifact> resourceJars = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
  private ImmutableList<Artifact> classpathResources = ImmutableList.of();
  private List<Artifact> messages = ImmutableList.of();
  private JavaToolchainProvider javaToolchain;
  private NestedSet<Artifact> additionalInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER);

  @CanIgnoreReturnValue
  public ResourceJarActionBuilder setOutputJar(Artifact outputJar) {
    this.outputJar = outputJar;
    return this;
  }

  @CanIgnoreReturnValue
  public ResourceJarActionBuilder setAdditionalInputs(NestedSet<Artifact> additionalInputs) {
    this.additionalInputs = additionalInputs;
    return this;
  }

  @CanIgnoreReturnValue
  public ResourceJarActionBuilder setClasspathResources(
      ImmutableList<Artifact> classpathResources) {
    this.classpathResources = classpathResources;
    return this;
  }

  @CanIgnoreReturnValue
  public ResourceJarActionBuilder setResources(Map<PathFragment, Artifact> resources) {
    this.resources = resources;
    return this;
  }

  @CanIgnoreReturnValue
  public ResourceJarActionBuilder setResourceJars(NestedSet<Artifact> resourceJars) {
    this.resourceJars = resourceJars;
    return this;
  }

  @CanIgnoreReturnValue
  public ResourceJarActionBuilder setTranslations(ImmutableList<Artifact> translations) {
    this.messages = translations;
    return this;
  }

  @CanIgnoreReturnValue
  public ResourceJarActionBuilder setJavaToolchain(JavaToolchainProvider javaToolchain) {
    this.javaToolchain = javaToolchain;
    return this;
  }

  public void build(JavaSemantics semantics, RuleContext ruleContext, String execGroup) {
    checkNotNull(outputJar, "outputJar must not be null");
    checkNotNull(javaToolchain, "javaToolchain must not be null");
    checkNotNull(javaToolchain.getJavaRuntime(), "javabase must not be null");

    SpawnAction.Builder builder = new SpawnAction.Builder();
    CustomCommandLine.Builder command =
        CustomCommandLine.builder()
            .add("--normalize")
            .add("--dont_change_compression")
            .add("--exclude_build_data")
            .addExecPath("--output", outputJar);
    if (!resourceJars.isEmpty()) {
      command.addExecPaths("--sources", resourceJars);
    }
    if (!resources.isEmpty() || !messages.isEmpty()) {
      command.add("--resources");
      for (Map.Entry<PathFragment, Artifact> resource : resources.entrySet()) {
        addAsResourcePrefixedExecPath(resource.getKey(), resource.getValue(), command);
      }
      for (Artifact message : messages) {
        addAsResourcePrefixedExecPath(
            semantics.getDefaultJavaResourcePath(message.getRootRelativePath()), message, command);
      }
    }
    if (!classpathResources.isEmpty()) {
      command.addExecPaths("--classpath_resources", classpathResources);
    }

    ruleContext.registerAction(
        builder
            .setExecutable(javaToolchain.getSingleJar())
            .useDefaultShellEnvironment()
            .addOutput(outputJar)
            .addInputs(messages)
            .addInputs(resources.values())
            .addTransitiveInputs(resourceJars)
            .addTransitiveInputs(additionalInputs)
            .addInputs(classpathResources)
            .addCommandLine(command.build(), PARAM_FILE_INFO)
            .setProgressMessage("Building Java resource jar")
            .setMnemonic(MNEMONIC)
            .setExecGroup(execGroup)
            .build(ruleContext));
  }

  private static void addAsResourcePrefixedExecPath(
      PathFragment resourcePath, Artifact artifact, CustomCommandLine.Builder builder) {
    PathFragment execPath = artifact.getExecPath();
    if (execPath.equals(resourcePath)) {
      builder.addFormatted("%s", resourcePath);
    } else {
      builder.addFormatted("%s:%s", execPath, resourcePath);
    }
  }
}
