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

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

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
import java.nio.charset.Charset;
import java.util.Objects;
import javax.annotation.concurrent.Immutable;

/**
 * An object that encapsulates how a params file should be constructed: what is the filetype,
 * what charset to use and what prefix (typically "@") to use.
 */
@Immutable
public final class ParamFileInfo {
  private final ParameterFileType fileType;
  private final Charset charset;
  private final String flagFormatString;
  private final boolean always;

  private ParamFileInfo(
      ParameterFileType fileType,
      Charset charset,
      String flagFormatString,
      boolean always) {
    this.fileType = Preconditions.checkNotNull(fileType);
    this.charset = Preconditions.checkNotNull(charset);
    this.flagFormatString = Preconditions.checkNotNull(flagFormatString);
    this.always = always;
  }

  /**
   * Returns the file type.
   */
  public ParameterFileType getFileType() {
    return fileType;
  }

  /**
   * Returns the charset.
   */
  public Charset getCharset() {
    return charset;
  }

  /** Returns the format string for the params filename on the command line (typically "@%s"). */
  public String getFlagFormatString() {
    return flagFormatString;
  }

  /** Returns true if a params file should always be used. */
  public boolean always() {
    return always;
  }

  @Override
  public int hashCode() {
    return Objects.hash(charset, flagFormatString, fileType, always);
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof ParamFileInfo)) {
      return false;
    }
    ParamFileInfo other = (ParamFileInfo) obj;
    return fileType.equals(other.fileType)
        && charset.equals(other.charset)
        && flagFormatString.equals(other.flagFormatString)
        && always == other.always;
  }

  public static Builder builder(ParameterFileType parameterFileType) {
    return new Builder(parameterFileType);
  }

  /** Builder for a ParamFileInfo. */
  public static class Builder {
    private final ParameterFileType fileType;
    private Charset charset = ISO_8859_1;
    private String flagFormatString = "@%s";
    private boolean always;

    private Builder(ParameterFileType fileType) {
      this.fileType = fileType;
    }

    /** Sets the encoding to write the parameter file with. */
    public Builder setCharset(Charset charset) {
      this.charset = charset;
      return this;
    }

    /**
     * Sets a format string to use for the flag that is passed to original command.
     *
     * <p>The format string must have a single "%s" that will be replaced by the execution path to
     * the param file.
     */
    public Builder setFlagFormatString(String flagFormatString) {
      this.flagFormatString = flagFormatString;
      return this;
    }

    /** Set whether the parameter file is always used, regardless of parameter file length. */
    public Builder setUseAlways(boolean always) {
      this.always = always;
      return this;
    }

    public ParamFileInfo build() {
      return new ParamFileInfo(fileType, charset, flagFormatString, always);
    }
  }
}
