// 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.devtools.build.lib.actions.ActionExecutionContext;
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.IOException;
import java.io.OutputStream;
import java.util.Collection;

/**
 * Action to write to a file.
 * <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 {

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

  /**
   * We keep it as a CharSequence for memory-efficiency reasons. The toString()
   * method of the object represents the content of the file.
   *
   * <p>For example, this allows us to keep a {@code List<Artifact>} wrapped
   * in a {@code LazyString} instead of the string representation of the concatenation.
   * This saves memory because the Artifacts are shared objects but the
   * resulting String is not.
   */
  private final CharSequence fileContents;

  /**
   * Creates a new FileWriteAction instance without inputs using UTF8 encoding.
   *
   * @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 iff true will change the output file to be
   *   executable.
   */
  public FileWriteAction(ActionOwner owner, Artifact output, CharSequence fileContents,
      boolean makeExecutable) {
    this(owner, Artifact.NO_ARTIFACTS, output, fileContents, makeExecutable);
  }

  /**
   * Creates a new FileWriteAction instance using UTF8 encoding.
   *
   * @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.
   * @param fileContents the contents to be written to the file.
   * @param makeExecutable iff true will change the output file to be
   *   executable.
   */
  public FileWriteAction(ActionOwner owner, Collection<Artifact> inputs,
      Artifact output, CharSequence fileContents, boolean makeExecutable) {
    super(owner, inputs, output, makeExecutable);
    if (fileContents instanceof String && fileContents.length() > 256) {
      fileContents = new StoredAsUTF8((String) fileContents);
    }
    this.fileContents = fileContents;
  }

  private static final class StoredAsUTF8 extends LazyString {
    final byte[] bytes;

    StoredAsUTF8(String chars) {
      this.bytes = chars.getBytes(UTF_8);
    }

    @Override
    public String toString() {
      return new String(bytes, UTF_8);
    }
  }

  /**
   * Creates a new FileWriteAction instance using UTF8 encoding.
   *
   * @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.
   * @param makeExecutable iff true will change the output file to be
   *   executable.
   */
  protected FileWriteAction(ActionOwner owner, Collection<Artifact> inputs,
      Artifact output, boolean makeExecutable) {
    this(owner, inputs, output, "", makeExecutable);
  }

  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() {
    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(new FileWriteAction(
        ruleContext.getActionOwner(), scriptFileArtifact, contents, executable));
    return scriptFileArtifact;
  }
}
