// 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.devtools.build.lib.rules.android;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
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.vfs.PathFragment;
import java.util.ArrayList;
import java.util.List;

/** Builder for creating $android_resource_parser action. */
public class AndroidResourceParsingActionBuilder {

  private static final ResourceContainerToArtifacts RESOURCE_CONTAINER_TO_ARTIFACTS =
      new ResourceContainerToArtifacts();

  private static final ResourceContainerToArg RESOURCE_CONTAINER_TO_ARG =
      new ResourceContainerToArg();

  private final RuleContext ruleContext;
  private LocalResourceContainer primary;
  private Artifact output;

  private ResourceContainer resourceContainer;

  /**
   * @param ruleContext The RuleContext that was used to create the SpawnAction.Builder.
   */
  public AndroidResourceParsingActionBuilder(RuleContext ruleContext) {
    this.ruleContext = ruleContext;
  }

  /**
   * Set the resource container to parse.
   */
  public AndroidResourceParsingActionBuilder setParse(LocalResourceContainer primary) {
    this.primary = primary;
    return this;
  }

  /**
   * Set the artifact location for the output protobuf.
   */
  public AndroidResourceParsingActionBuilder setOutput(Artifact output) {
    this.output = output;
    return this;
  }

  /** Set the primary resources. */
  public AndroidResourceParsingActionBuilder withPrimary(ResourceContainer resourceContainer) {
    this.resourceContainer = resourceContainer;
    return this;
  }

  private static class ResourceContainerToArg implements Function<LocalResourceContainer, String> {

    public ResourceContainerToArg() {
    }

    @Override
    public String apply(LocalResourceContainer container) {
      return new StringBuilder()
          .append(convertRoots(container.getResourceRoots()))
          .append(":")
          .append(convertRoots(container.getAssetRoots()))
          .toString();
    }
  }

  private static class ResourceContainerToArtifacts
      implements Function<LocalResourceContainer, NestedSet<Artifact>> {

    public ResourceContainerToArtifacts() {
    }

    @Override
    public NestedSet<Artifact> apply(LocalResourceContainer container) {
      NestedSetBuilder<Artifact> artifacts = NestedSetBuilder.naiveLinkOrder();
      artifacts.addAll(container.getAssets());
      artifacts.addAll(container.getResources());
      return artifacts.build();
    }
  }

  private static String convertRoots(Iterable<PathFragment> roots) {
    return Joiner.on("#").join(Iterables.transform(roots, Functions.toStringFunction()));
  }

  public ResourceContainer build(ActionConstructionContext context) {
    CustomCommandLine.Builder builder = new CustomCommandLine.Builder();
    
    // Set the busybox tool.
    builder.add("--tool").add("PARSE").add("--");

    NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
    inputs.addAll(
        ruleContext
            .getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)
            .getRunfilesSupport()
            .getRunfilesArtifactsWithoutMiddlemen());

    Preconditions.checkNotNull(primary);
    builder.add("--primaryData").add(RESOURCE_CONTAINER_TO_ARG.apply(primary));
    inputs.addTransitive(RESOURCE_CONTAINER_TO_ARTIFACTS.apply(primary));

    List<Artifact> outs = new ArrayList<>();
    Preconditions.checkNotNull(output);
    builder.addExecPath("--output", output);
    outs.add(output);

    SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder();
    // Create the spawn action.
    ruleContext.registerAction(
        spawnActionBuilder
            .useParameterFile(ParameterFileType.UNQUOTED)
            .addTransitiveInputs(inputs.build())
            .addOutputs(ImmutableList.copyOf(outs))
            .setCommandLine(builder.build())
            .setExecutable(
                ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
            .setProgressMessage("Parsing Android resources for " + ruleContext.getLabel())
            .setMnemonic("AndroidResourceParser")
            .build(context));
    
    return resourceContainer.toBuilder().setSymbols(output).build();
  }
}
