/*
 * Copyright 2013-present Facebook, Inc.
 *
 * 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.facebook.buck.shell;

import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.AbstractBuildRuleBuilder;
import com.facebook.buck.rules.AbstractBuildRuleBuilderParams;
import com.facebook.buck.rules.AbstractCachingBuildRule;
import com.facebook.buck.rules.BinaryBuildRule;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.ResourcesAttributeBuilder;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePaths;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.fs.MakeCleanDirectoryStep;
import com.facebook.buck.util.BuckConstant;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class ShBinaryRule extends AbstractCachingBuildRule implements BinaryBuildRule {

  private final Path main;
  private final ImmutableSet<SourcePath> resources;

  /** The path where the output will be written. */
  private final Path output;

  protected ShBinaryRule(BuildRuleParams buildRuleParams,
      Path main,
      ImmutableSet<SourcePath> resources) {
    super(buildRuleParams);
    this.main = Preconditions.checkNotNull(main);
    this.resources = Preconditions.checkNotNull(resources);

    BuildTarget target = buildRuleParams.getBuildTarget();
    this.output = Paths.get(String.format("%s/%s%s.sh",
        BuckConstant.GEN_DIR,
        target.getBasePathWithSlash(),
        target.getShortName()));
  }

  @Override
  protected Iterable<String> getInputsToCompareToOutput() {
    return Iterables.concat(ImmutableList.of(main.toString()),
        SourcePaths.filterInputsToCompareToOutput(resources));
  }

  @Override
  protected List<Step> buildInternal(BuildContext context) throws IOException {
    MakeCleanDirectoryStep mkdir = new MakeCleanDirectoryStep(output.getParent().toString());

    // Generate an .sh file that builds up an environment and invokes the user's script.
    // This generated .sh file will be returned by getExecutableCommand().
    GenerateShellScriptStep generateShellScript = new GenerateShellScriptStep(
        Paths.get(getBuildTarget().getBasePath()),
        main,
        SourcePaths.toPaths(resources, context),
        output);

    return ImmutableList.of(mkdir, generateShellScript);
  }

  @Override
  public BuildRuleType getType() {
    return BuildRuleType.SH_BINARY;
  }

  @Override
  public String getPathToOutputFile() {
    return output.toString();
  }

  @Override
  public String getExecutableCommand(ProjectFilesystem projectFilesystem) {
    return projectFilesystem.getFileForRelativePath(output.toString()).getAbsolutePath();
  }

  public static Builder newShBinaryBuilder(AbstractBuildRuleBuilderParams params) {
    return new Builder(params);
  }

  public static class Builder extends AbstractBuildRuleBuilder<ShBinaryRule>
      implements ResourcesAttributeBuilder {

    private Path main;
    private ImmutableSet.Builder<SourcePath> resources = ImmutableSet.builder();

    protected Builder(AbstractBuildRuleBuilderParams params) {
      super(params);
    }

    @Override
    public ShBinaryRule build(BuildRuleResolver ruleResolver) {
      BuildRuleParams params = createBuildRuleParams(ruleResolver);
      return new ShBinaryRule(params,
          main,
          resources.build());
    }

    public Builder setMain(Path main) {
      this.main = main;
      return this;
    }

    @Override
    public Builder addResource(SourcePath relativePathToResource) {
      resources.add(relativePathToResource);
      return this;
    }
  }
}
