// 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.android;

import com.android.builder.core.VariantType;
import com.android.repository.Revision;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
 * Builder for AAPT command lines, with support for making flags conditional on build tools version
 * and variant type.
 */
public class AaptCommandBuilder {

  private final ImmutableList.Builder<String> flags = new ImmutableList.Builder<>();
  private Revision buildToolsVersion;
  private VariantType variantType;

  public AaptCommandBuilder(Path aapt) {
    flags.add(aapt.toString());
  }

  /** Sets the build tools version to be used for {@link #whenVersionIsAtLeast}. */
  public AaptCommandBuilder forBuildToolsVersion(@Nullable Revision buildToolsVersion) {
    Preconditions.checkState(
        this.buildToolsVersion == null, "A build tools version was already specified.");
    this.buildToolsVersion = buildToolsVersion;
    return this;
  }

  /** Sets the variant type to be used for {@link #whenVariantIs}. */
  public AaptCommandBuilder forVariantType(VariantType variantType) {
    Preconditions.checkNotNull(variantType);
    Preconditions.checkState(this.variantType == null, "A variant type was already specified.");
    this.variantType = variantType;
    return this;
  }

  /** Adds a single flag to the builder. */
  public AaptCommandBuilder add(String flag) {
    flags.add(flag);
    return this;
  }

  /**
   * Adds a flag to the builder, along with a string value. The two will be added as different words
   * in the final command line. If the value is {@code null}, neither the flag nor the value will be
   * added.
   */
  public AaptCommandBuilder add(String flag, @Nullable String value) {
    Preconditions.checkNotNull(flag);
    if (!Strings.isNullOrEmpty(value)) {
      flags.add(flag);
      flags.add(value);
    }
    return this;
  }

  /**
   * Adds a flag to the builder, along with a path value. The path will be converted to a string
   * using {@code toString}, then the flag and the path will be added to the final command line as
   * different words. If the value is {@code null}, neither the flag nor the path will be added.
   *
   * @see #add(String,String)
   */
  public AaptCommandBuilder add(String flag, @Nullable Path path) {
    Preconditions.checkNotNull(flag);
    if (path != null) {
      add(flag, path.toString());
    }
    return this;
  }

  /**
   * Adds a flag to the builder multiple times, once for each value in the given collection. {@code
   * null} values will be skipped. If the collection is empty, nothing will be added. The values
   * will be added in the source collection's iteration order.
   *
   * <p>ex. If {@code flag} is {@code "-0"} and {@code values} contains the values {@code "png"},
   * {@code null}, and {@code "gif"}, then four words will be added to the final command line:
   * {@code "-0", "png", "-0", "gif"}.
   */
  public AaptCommandBuilder addRepeated(String flag, Collection<String> values) {
    Preconditions.checkNotNull(flag);
    for (String value : values) {
      add(flag, value);
    }
    return this;
  }

  /**
   * Adds a flag to the builder multiple times, once for each value in the given collection. {@code
   * null} values will be skipped. If the collection is empty, nothing will be added. The values
   * will be added in the source collection's iteration order. See {@link
   * AaptCommandBuilder#addRepeated(String, Collection)} for more information. If the collection
   * exceed 200 items, the values will be written to a file and passed as &lt;flag&gt @&lt;file&gt;.
   */
  public AaptCommandBuilder addParameterableRepeated(
      final String flag, Collection<String> values, Path workingDirectory) throws IOException {
    Preconditions.checkNotNull(flag);
    Preconditions.checkNotNull(workingDirectory);
    if (values.size() > 200) {
      add(
          flag,
          "@"
              + Files.write(
                  Files.createDirectories(workingDirectory).resolve("params" + flag),
                  ImmutableList.of(values.stream().collect(Collectors.joining(" ")))));
    } else {
      addRepeated(flag, values);
    }
    return this;
  }

  /** Adds the next flag to the builder only if the condition is true. */
  public ConditionalAaptCommandBuilder when(boolean condition) {
    if (condition) {
      return new SuccessfulConditionCommandBuilder(this);
    } else {
      return new FailedConditionCommandBuilder(this);
    }
  }

  /** Adds the next flag to the builder only if the variant type is the passed-in type. */
  public ConditionalAaptCommandBuilder whenVariantIs(VariantType variantType) {
    Preconditions.checkNotNull(variantType);
    return when(this.variantType == variantType);
  }

  /**
   * Adds the next flag to the builder only if the build tools version is unspecified or is greater
   * than or equal to the given version.
   */
  public ConditionalAaptCommandBuilder whenVersionIsAtLeast(Revision requiredVersion) {
    Preconditions.checkNotNull(requiredVersion);
    return when(buildToolsVersion == null || buildToolsVersion.compareTo(requiredVersion) >= 0);
  }

  /** Assembles the full command line as a list. */
  public List<String> build() {
    return flags.build();
  }

  public AaptCommandBuilder add(String flag, Optional<Path> optionalPath) {
    Preconditions.checkNotNull(flag);
    Preconditions.checkNotNull(optionalPath);
    optionalPath.map(p -> add(flag, p));
    return this;
  }

  /** Wrapper for potentially adding flags to an AaptCommandBuilder based on a conditional. */
  public interface ConditionalAaptCommandBuilder {
    /**
     * Adds a single flag to the builder if the condition was true.
     *
     * @see AaptCommandBuilder#add(String)
     */
    AaptCommandBuilder thenAdd(String flag);

    /**
     * Adds a single flag and associated string value to the builder if the value is non-null and
     * the condition was true.
     *
     * @see AaptCommandBuilder#add(String,String)
     */
    AaptCommandBuilder thenAdd(String flag, @Nullable String value);

    /**
     * Adds a single flag and associated path value to the builder if the value is non-null and the
     * condition was true.
     *
     * @see AaptCommandBuilder#add(String,Path)
     */
    AaptCommandBuilder thenAdd(String flag, @Nullable Path value);

    /**
     * Adds a single flag and associated path value to the builder if the value is non-null and the
     * condition was true.
     *
     * @see AaptCommandBuilder#add(String,Optional)
     */
    AaptCommandBuilder thenAdd(String flag, Optional<Path> value);

    /**
     * Adds the values in the collection to the builder, each preceded by the given flag, if the
     * collection was non-empty and the condition was true.
     *
     * @see AaptCommandBuilder#addRepeated(String,Collection<String>)
     */
    AaptCommandBuilder thenAddRepeated(String flag, Collection<String> values);
  }

  /**
   * Forwarding implementation of ConditionalAaptCommandBuilder returned when a condition is true.
   */
  private static class SuccessfulConditionCommandBuilder implements ConditionalAaptCommandBuilder {
    private final AaptCommandBuilder originalCommandBuilder;

    public SuccessfulConditionCommandBuilder(AaptCommandBuilder originalCommandBuilder) {
      this.originalCommandBuilder = originalCommandBuilder;
    }

    @Override
    public AaptCommandBuilder thenAdd(String flag) {
      return originalCommandBuilder.add(flag);
    }

    @Override
    public AaptCommandBuilder thenAdd(String flag, @Nullable String value) {
      return originalCommandBuilder.add(flag, value);
    }

    @Override
    public AaptCommandBuilder thenAdd(String flag, @Nullable Path value) {
      return originalCommandBuilder.add(flag, value);
    }

    @Override
    public AaptCommandBuilder thenAdd(String flag, @Nullable Optional<Path> value) {
      return originalCommandBuilder.add(flag, value);
    }

    @Override
    public AaptCommandBuilder thenAddRepeated(String flag, Collection<String> values) {
      return originalCommandBuilder.addRepeated(flag, values);
    }
  }

  /** Null implementation of ConditionalAaptCommandBuilder returned when a condition is false. */
  private static class FailedConditionCommandBuilder implements ConditionalAaptCommandBuilder {
    private final AaptCommandBuilder originalCommandBuilder;

    public FailedConditionCommandBuilder(AaptCommandBuilder originalCommandBuilder) {
      this.originalCommandBuilder = originalCommandBuilder;
    }

    @Override
    public AaptCommandBuilder thenAdd(String flag) {
      Preconditions.checkNotNull(flag);
      return originalCommandBuilder;
    }

    @Override
    public AaptCommandBuilder thenAdd(String flag, @Nullable String value) {
      Preconditions.checkNotNull(flag);
      return originalCommandBuilder;
    }

    @Override
    public AaptCommandBuilder thenAdd(String flag, @Nullable Path value) {
      Preconditions.checkNotNull(flag);
      return originalCommandBuilder;
    }

    @Override
    public AaptCommandBuilder thenAdd(String flag, Optional<Path> value) {
      Preconditions.checkNotNull(flag);
      Preconditions.checkNotNull(value);
      return originalCommandBuilder;
    }

    @Override
    public AaptCommandBuilder thenAddRepeated(String flag, Collection<String> values) {
      Preconditions.checkNotNull(flag);
      Preconditions.checkNotNull(values);
      return originalCommandBuilder;
    }
  }

  /**
   * Executes command and returns log.
   *
   * @throws IOException when the process cannot execute.
   */
  public String execute(String action) throws IOException {
    final StringBuilder processLog = new StringBuilder();
    List<String> command = build();

    final Process process = new ProcessBuilder().command(command).redirectErrorStream(true).start();
    processLog.append("Command: ");
    Joiner.on("\\\n\t").appendTo(processLog, command);
    processLog.append("\nOutput:\n");
    final InputStreamReader stdout =
        new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8);
    while (process.isAlive()) {
      processLog.append(CharStreams.toString(stdout));
    }
    // Make sure the full stdout is read.
    while (stdout.ready()) {
      processLog.append(CharStreams.toString(stdout));
    }
    if (process.exitValue() != 0) {
      throw new RuntimeException(String.format("Error during %s:", action) + "\n" + processLog);
    }
    return processLog.toString();
  }
}
