/** Arguments for creating a new container via SSH */
public class CreateSshContainerOptions
    extends CreateContainerBasicOptions<CreateSshContainerOptions>
    implements CreateRemoteContainerOptions {

  private static final long serialVersionUID = -1171578973712670970L;

  public static final String DEFAULT_PRIVATE_KEY_FILE =
      System.getProperty("user.home") + File.separatorChar + ".ssh" + File.separatorChar + "id_rsa";

  static final Integer DEFAULT_SSH_RETRIES = 1;
  static final Integer DEFAULT_SSH_PORT = 22;

  private String username;
  private String password;
  private String host;
  private Integer port = DEFAULT_SSH_PORT;
  private String path = "/usr/local/fusesource/container";
  private Integer sshRetries = DEFAULT_SSH_RETRIES;
  private Integer retryDelay = 1;
  private String privateKeyFile = DEFAULT_PRIVATE_KEY_FILE;
  private String passPhrase;
  private CreateEnsembleOptions createEnsembleOptions = CreateEnsembleOptions.build();

  public CreateSshContainerOptions() {
    this.providerType = "ssh";
  }

  @Override
  public String toString() {
    return "createSshContainer("
        + getUsername()
        + "@"
        + getHost()
        + ":"
        + getPort()
        + " "
        + getPath()
        + ")";
  }

  public CreateSshContainerOptions username(final String username) {
    this.username = username;
    return this;
  }

  public CreateSshContainerOptions password(final String password) {
    this.password = password;
    return this;
  }

  public CreateSshContainerOptions host(final String host) {
    this.host = host;
    return this;
  }

  public CreateSshContainerOptions port(final Integer port) {
    this.port = port;
    return this;
  }

  public CreateSshContainerOptions path(final String path) {
    this.path = path;
    return this;
  }

  public CreateSshContainerOptions sshRetries(final Integer sshRetries) {
    this.sshRetries = sshRetries;
    return this;
  }

  public CreateSshContainerOptions retryDelay(final Integer retryDelay) {
    this.retryDelay = retryDelay;
    return this;
  }

  public CreateSshContainerOptions privateKeyFile(final String privateKeyFile) {
    this.privateKeyFile = privateKeyFile;
    return this;
  }

  public CreateSshContainerOptions passPhrase(final String passPhrase) {
    this.passPhrase = passPhrase;
    return this;
  }

  public CreateSshContainerOptions createEnsembleOptions(
      final CreateEnsembleOptions createEnsembleOptions) {
    this.createEnsembleOptions = createEnsembleOptions;
    return this;
  }

  public String getUsername() {
    try {
      return username != null && !username.isEmpty()
          ? username
          : getProviderURI().getUserInfo().split(":")[0];
    } catch (Exception ex) {
      throw new IllegalStateException("Username should be part of the url or explicitly specified");
    }
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    if (password != null && !password.isEmpty()) {
      return password;
    } else if (getProviderURI() != null
        && getProviderURI().getUserInfo() != null
        && getProviderURI().getUserInfo().contains(":")) {
      return getProviderURI().getUserInfo().split(":")[1];
    } else {
      return null;
    }
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getHost() {
    return host != null && !host.isEmpty() ? host : getProviderURI().getHost();
  }

  public void setHost(String host) {
    this.host = host;
  }

  public Integer getPort() {
    return port != null && port != 0
        ? port
        : (getProviderURI() != null && getProviderURI().getPort() != 0
            ? getProviderURI().getPort()
            : DEFAULT_SSH_PORT);
  }

  public void setPort(Integer port) {
    this.port = port;
  }

  public Integer getSshRetries() {
    return sshRetries != null ? sshRetries : DEFAULT_SSH_RETRIES;
  }

  public void setSshRetries(Integer sshRetries) {
    this.sshRetries = sshRetries;
  }

  public String getPath() {
    return path;
  }

  public void setPath(String path) {
    this.path = path;
  }

  public Integer getRetryDelay() {
    return retryDelay;
  }

  public void setRetryDelay(Integer retryDelay) {
    this.retryDelay = retryDelay;
  }

  public String getPrivateKeyFile() {
    // We check for a parameter first as the privateKeyFile has a default value assigned.
    return getParameters().get("privateKeyFile") != null
        ? getParameters().get("privateKeyFile")
        : privateKeyFile;
  }

  public void setPrivateKeyFile(String privateKeyFile) {
    this.privateKeyFile = privateKeyFile;
  }

  public String getPassPhrase() {
    return passPhrase;
  }

  public void setPassPhrase(String passPhrase) {
    this.passPhrase = passPhrase;
  }

  public CreateEnsembleOptions getCreateEnsembleOptions() {
    return createEnsembleOptions;
  }

  public void setCreateEnsembleOptions(CreateEnsembleOptions createEnsembleOptions) {
    this.createEnsembleOptions = createEnsembleOptions;
  }
}