// Copyright 2014 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.analysis.actions;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.annotations.VisibleForTesting;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.LazyString;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * Action to write a file whose contents are known at analysis time.
 *
 * <p>The output is always UTF-8 encoded.
 *
 * <p>TODO(bazel-team): Choose a better name to distinguish this class from {@link
 * BinaryFileWriteAction}.
 */
@Immutable // if fileContents is immutable
public final class FileWriteAction extends AbstractFileWriteAction {

  /** Whether or not transparent compression is possible. */
  public static enum Compression {
    /** No compression, ever. */
    DISALLOW,
    /** May compress. */
    ALLOW;

    /** Maps true/false to allow/disallow respectively. */
    public static Compression fromBoolean(boolean allow) {
      return allow ? ALLOW : DISALLOW;
    }
  }

  private static final String GUID = "332877c7-ca9f-4731-b387-54f620408522";

  /**
   * The contents may be lazily computed or compressed.
   *
   * <p>If the object representing the contents is a {@code String}, its length is greater than
   * {@code COMPRESS_CHARS_THRESHOLD}, and compression is enabled, then the gzipped bytestream of
   * the contents will be stored in place of the string itself. This compression is transparent and
   * does not affect the output file.
   *
   * <p>Otherwise, if the object represents a lazy computation, it will not be forced until {@link
   * #getFileContents()} is called. An example where this may come in handy is if the contents are
   * the concatenation of the string representations of a series of artifacts. Then the client code
   * can wrap a {@code List<Artifact>} in a {@code LazyString}, which saves memory since the
   * artifacts are shared objects whereas a string is not.
   */
  private final CharSequence fileContents;

  /** Minimum length (in chars) for content to be eligible for compression. */
  private static final int COMPRESS_CHARS_THRESHOLD = 256;

  private FileWriteAction(
      ActionOwner owner,
      Iterable<Artifact> inputs,
      Artifact output,
      CharSequence fileContents,
      boolean makeExecutable,
      Compression allowCompression) {
    super(owner, inputs, output, makeExecutable);
    if (allowCompression == Compression.ALLOW
        && fileContents instanceof String
        && fileContents.length() > COMPRESS_CHARS_THRESHOLD) {
      fileContents = new CompressedString((String) fileContents);
    }
    this.fileContents = fileContents;
  }

  /**
   * Creates a new FileWriteAction instance with inputs and empty content.
   *
   * <p>This is useful for producing an artifact that, if built, will ensure that the generating
   * actions for its inputs are run. The output file is non-executable.
   *
   * @param owner the action owner
   * @param inputs the Artifacts that this Action depends on
   * @param output the Artifact that will be created by executing this Action
   */
  public static FileWriteAction createEmptyWithInputs(
      ActionOwner owner, Iterable<Artifact> inputs, Artifact output) {
    return new FileWriteAction(owner, inputs, output, "", false, Compression.DISALLOW);
  }

  /**
   * Creates a new FileWriteAction instance with direct control over whether or not transparent
   * compression may be used.
   *
   * @param owner the action owner
   * @param output the Artifact that will be created by executing this Action
   * @param fileContents the contents to be written to the file
   * @param makeExecutable whether the output file is made executable
   * @param allowCompression whether (transparent) compression is enabled
   */
  public static FileWriteAction create(
      ActionOwner owner,
      Artifact output,
      CharSequence fileContents,
      boolean makeExecutable,
      Compression allowCompression) {
    return new FileWriteAction(
        owner, Artifact.NO_ARTIFACTS, output, fileContents, makeExecutable, allowCompression);
  }

  /**
   * Creates a new FileWriteAction instance.
   *
   * <p>There are no inputs. Transparent compression is controlled by the {@code
   * --experimental_transparent_compression} flag. No reference to the {@link RuleContext} will be
   * maintained.
   *
   * @param context the rule context
   * @param output the Artifact that will be created by executing this Action
   * @param fileContents the contents to be written to the file
   * @param makeExecutable whether the output file is made executable
   */
  public static FileWriteAction create(
      RuleContext context, Artifact output, CharSequence fileContents, boolean makeExecutable) {
    return new FileWriteAction(
        context.getActionOwner(),
        Artifact.NO_ARTIFACTS,
        output,
        fileContents,
        makeExecutable,
        context.getConfiguration().transparentCompression());
  }

  private static final class CompressedString extends LazyString {
    final byte[] bytes;
    final int uncompressedSize;

    CompressedString(String chars) {
      byte[] dataToCompress = chars.getBytes(UTF_8);
      ByteArrayOutputStream byteStream = new ByteArrayOutputStream(dataToCompress.length);
      try (GZIPOutputStream zipStream = new GZIPOutputStream(byteStream)) {
        zipStream.write(dataToCompress);
      } catch (IOException e) {
        // This should be impossible since we're writing to a byte array.
        throw new RuntimeException(e);
      }
      this.uncompressedSize = dataToCompress.length;
      this.bytes = byteStream.toByteArray();
    }

    @Override
    public String toString() {
      byte[] uncompressedBytes = new byte[uncompressedSize];
      try (GZIPInputStream zipStream = new GZIPInputStream(new ByteArrayInputStream(bytes))) {
        int read;
        int totalRead = 0;
        while (totalRead < uncompressedSize
            && (read = zipStream.read(uncompressedBytes, totalRead, uncompressedSize - totalRead))
                != -1) {
          totalRead += read;
        }
        if (totalRead != uncompressedSize) {
          // This should be impossible.
          throw new RuntimeException("Corrupt byte buffer in FileWriteAction.");
        }
      } catch (IOException e) {
        // This should be impossible since we're reading from a byte array.
        throw new RuntimeException(e);
      }
      return new String(uncompressedBytes, UTF_8);
    }
  }

  @VisibleForTesting
  boolean usesCompression() {
    return fileContents instanceof CompressedString;
  }

  /**
   * Returns the string contents to be written.
   *
   * <p>Note that if the string is lazily computed or compressed, calling this method will force its
   * computation or decompression. No attempt is made by FileWriteAction to cache the result.
   */
  public String getFileContents() {
    return fileContents.toString();
  }

  @Override
  public String getSkylarkContent() {
    return getFileContents();
  }

  /**
   * Create a DeterministicWriter for the content of the output file as provided by
   * {@link #getFileContents()}.
   */
  @Override
  public DeterministicWriter newDeterministicWriter(ActionExecutionContext ctx) {
    return new DeterministicWriter() {
      @Override
      public void writeOutputFile(OutputStream out) throws IOException {
        out.write(getFileContents().getBytes(UTF_8));
      }
    };
  }

  /** Computes the Action key for this action by computing the fingerprint for the file contents. */
  @Override
  protected String computeKey(ActionKeyContext actionKeyContext) {
    Fingerprint f = new Fingerprint();
    f.addString(GUID);
    f.addString(String.valueOf(makeExecutable));
    f.addString(getFileContents());
    return f.hexDigestAndReset();
  }

  /**
   * Creates a FileWriteAction to write contents to the resulting artifact fileName in the genfiles
   * root underneath the package path.
   *
   * @param ruleContext the ruleContext that will own the action of creating this file
   * @param fileName name of the file to create
   * @param contents data to write to file
   * @param executable flags that file should be marked executable
   * @return Artifact describing the file to create
   */
  public static Artifact createFile(
      RuleContext ruleContext, String fileName, CharSequence contents, boolean executable) {
    Artifact scriptFileArtifact = ruleContext.getPackageRelativeArtifact(
        fileName, ruleContext.getConfiguration().getGenfilesDirectory(
            ruleContext.getRule().getRepository()));
    ruleContext.registerAction(
        FileWriteAction.create(ruleContext, scriptFileArtifact, contents, executable));
    return scriptFileArtifact;
  }
}
