/*
 * Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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 org.apache.hadoop.yarn.service.api.records;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * An Service resource has the following attributes.
 **/
@InterfaceAudience.Public
@InterfaceStability.Unstable
@ApiModel(description = "An Service resource has the following attributes.")
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaClientCodegen", date = "2016-06-02T08:15:05.615-07:00")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "name", "version", "description", "state", "resource",
    "number_of_containers", "lifetime", "containers" })
public class Service extends BaseResource {
  private static final long serialVersionUID = -4491694636566094885L;

  private String name = null;
  private String id = null;
  private Artifact artifact = null;
  private Resource resource = null;
  @JsonProperty("launch_time")
  @XmlElement(name = "launch_time")
  private Date launchTime = null;
  @JsonProperty("number_of_running_containers")
  @XmlElement(name = "number_of_running_containers")
  private Long numberOfRunningContainers = null;
  private Long lifetime = null;
  private List<Component> components = new ArrayList<>();
  private Configuration configuration = new Configuration();
  private ServiceState state = null;
  private Map<String, String> quicklinks = new HashMap<>();
  private String queue = null;
  @JsonProperty("kerberos_principal")
  @XmlElement(name = "kerberos_principal")
  private KerberosPrincipal kerberosPrincipal = new KerberosPrincipal();
  private String version = null;
  private String description = null;
  private String dockerClientConfig = null;

  /**
   * A unique service name.
   **/
  public Service name(String name) {
    this.name = name;
    return this;
  }

  @ApiModelProperty(example = "null", required = true, value = "A unique service name.")
  @JsonProperty("name")
  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  /**
   * A unique service id.
   **/
  public Service id(String id) {
    this.id = id;
    return this;
  }

  @ApiModelProperty(example = "null", value = "A unique service id.")
  @JsonProperty("id")
  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  @ApiModelProperty(example = "null", required = true,
      value = "Version of the service.")
  @JsonProperty("version")
  public String getVersion() {
    return version;
  }

  public void setVersion(String version) {
    this.version = version;
  }

  /**
   * Version of the service.
   */
  public Service version(String version) {
    this.version = version;
    return this;
  }

  @ApiModelProperty(example = "null", value = "Description of the service.")
  @JsonProperty("description")
  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  /**
   * Description of the service.
   */
  public Service description(String description) {
    this.description = description;
    return this;
  }

  /**
   * Artifact of single-component services. Mandatory if components
   * attribute is not specified.
   **/
  public Service artifact(Artifact artifact) {
    this.artifact = artifact;
    return this;
  }

  @ApiModelProperty(example = "null", value = "Artifact of single-component services. Mandatory if components attribute is not specified.")
  @JsonProperty("artifact")
  public Artifact getArtifact() {
    return artifact;
  }

  public void setArtifact(Artifact artifact) {
    this.artifact = artifact;
  }

  /**
   * Resource of single-component services or the global default for
   * multi-component services. Mandatory if it is a single-component
   * service and if cpus and memory are not specified at the Service
   * level.
   **/
  public Service resource(Resource resource) {
    this.resource = resource;
    return this;
  }

  @ApiModelProperty(example = "null", value = "Resource of single-component services or the global default for multi-component services. Mandatory if it is a single-component service and if cpus and memory are not specified at the Service level.")
  @JsonProperty("resource")
  public Resource getResource() {
    return resource;
  }

  public void setResource(Resource resource) {
    this.resource = resource;
  }

  /**
   * The time when the service was created, e.g. 2016-03-16T01:01:49.000Z.
   **/
  public Service launchTime(Date launchTime) {
    this.launchTime = launchTime == null ? null : (Date) launchTime.clone();
    return this;
  }

  @ApiModelProperty(example = "null", value = "The time when the service was created, e.g. 2016-03-16T01:01:49.000Z.")
  public Date getLaunchTime() {
    return launchTime == null ? null : (Date) launchTime.clone();
  }

  public void setLaunchTime(Date launchTime) {
    this.launchTime = launchTime == null ? null : (Date) launchTime.clone();
  }

  /**
   * In get response this provides the total number of running containers for
   * this service (across all components) at the time of request. Note, a
   * subsequent request can return a different number as and when more
   * containers get allocated until it reaches the total number of containers or
   * if a flex request has been made between the two requests.
   **/
  public Service numberOfRunningContainers(Long numberOfRunningContainers) {
    this.numberOfRunningContainers = numberOfRunningContainers;
    return this;
  }

  @ApiModelProperty(example = "null", value = "In get response this provides the total number of running containers for this service (across all components) at the time of request. Note, a subsequent request can return a different number as and when more containers get allocated until it reaches the total number of containers or if a flex request has been made between the two requests.")
  public Long getNumberOfRunningContainers() {
    return numberOfRunningContainers;
  }

  public void setNumberOfRunningContainers(Long numberOfRunningContainers) {
    this.numberOfRunningContainers = numberOfRunningContainers;
  }

  /**
   * Life time (in seconds) of the service from the time it reaches the
   * RUNNING_BUT_UNREADY state (after which it is automatically destroyed by YARN). For
   * unlimited lifetime do not set a lifetime value.
   **/
  public Service lifetime(Long lifetime) {
    this.lifetime = lifetime;
    return this;
  }

  @ApiModelProperty(example = "null", value = "Life time (in seconds) of the service from the time it reaches the RUNNING_BUT_UNREADY state (after which it is automatically destroyed by YARN). For unlimited lifetime do not set a lifetime value.")
  @JsonProperty("lifetime")
  public Long getLifetime() {
    return lifetime;
  }

  public void setLifetime(Long lifetime) {
    this.lifetime = lifetime;
  }

  /**
   * Components of an service.
   **/
  public Service components(List<Component> components) {
    this.components = components;
    return this;
  }

  @ApiModelProperty(example = "null", value = "Components of an service.")
  @JsonProperty("components")
  public List<Component> getComponents() {
    return components;
  }

  public void setComponents(List<Component> components) {
    this.components = components;
  }

  public void addComponent(Component component) {
    components.add(component);
  }

  public Component getComponent(String name) {
    for (Component component : components) {
      if (component.getName().equals(name)) {
        return component;
      }
    }
    return null;
  }

  /**
   * Config properties of an service. Configurations provided at the
   * service/global level are available to all the components. Specific
   * properties can be overridden at the component level.
   **/
  public Service configuration(Configuration configuration) {
    this.configuration = configuration;
    return this;
  }

  @ApiModelProperty(example = "null", value = "Config properties of an service. Configurations provided at the service/global level are available to all the components. Specific properties can be overridden at the component level.")
  @JsonProperty("configuration")
  public Configuration getConfiguration() {
    return configuration;
  }

  public void setConfiguration(Configuration configuration) {
    this.configuration = configuration;
  }

  /**
   * State of the service. Specifying a value for this attribute for the
   * POST payload raises a validation error. This attribute is available only in
   * the GET response of a started service.
   **/
  public Service state(ServiceState state) {
    this.state = state;
    return this;
  }

  @ApiModelProperty(example = "null", value = "State of the service. Specifying a value for this attribute for the POST payload raises a validation error. This attribute is available only in the GET response of a started service.")
  @JsonProperty("state")
  public ServiceState getState() {
    return state;
  }

  public void setState(ServiceState state) {
    this.state = state;
  }

  /**
   * A blob of key-value pairs of quicklinks to be exported for an service.
   **/
  public Service quicklinks(Map<String, String> quicklinks) {
    this.quicklinks = quicklinks;
    return this;
  }

  @ApiModelProperty(example = "null", value = "A blob of key-value pairs of quicklinks to be exported for an service.")
  @JsonProperty("quicklinks")
  public Map<String, String> getQuicklinks() {
    return quicklinks;
  }

  public void setQuicklinks(Map<String, String> quicklinks) {
    this.quicklinks = quicklinks;
  }

  /**
   * The YARN queue that this service should be submitted to.
   **/
  public Service queue(String queue) {
    this.queue = queue;
    return this;
  }

  @ApiModelProperty(example = "null", value = "The YARN queue that this service should be submitted to.")
  @JsonProperty("queue")
  public String getQueue() {
    return queue;
  }

  public void setQueue(String queue) {
    this.queue = queue;
  }

  public Service kerberosPrincipal(KerberosPrincipal kerberosPrincipal) {
    this.kerberosPrincipal = kerberosPrincipal;
    return this;
  }

  /**
   * The Kerberos Principal of the service.
   * @return kerberosPrincipal
   **/
  @ApiModelProperty(value = "The Kerberos Principal of the service")
  public KerberosPrincipal getKerberosPrincipal() {
    return kerberosPrincipal;
  }

  public void setKerberosPrincipal(KerberosPrincipal kerberosPrincipal) {
    this.kerberosPrincipal = kerberosPrincipal;
  }

  @JsonProperty("docker_client_config")
  @XmlElement(name = "docker_client_config")
  @SuppressWarnings("checkstyle:hiddenfield")
  public Service dockerClientConfig(String dockerClientConfig) {
    this.dockerClientConfig = dockerClientConfig;
    return this;
  }

  /**
   * The Docker client config for the service.
   * @return dockerClientConfig
   */
  @ApiModelProperty(value = "The Docker client config for the service")
  public String getDockerClientConfig() {
    return dockerClientConfig;
  }

  public void setDockerClientConfig(String dockerClientConfig) {
    this.dockerClientConfig = dockerClientConfig;
  }

  @Override
  public boolean equals(java.lang.Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Service service = (Service) o;
    return Objects.equals(this.name, service.name);
  }

  @Override
  public int hashCode() {
    return Objects.hash(name);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class Service {\n");

    sb.append("    name: ").append(toIndentedString(name)).append("\n");
    sb.append("    id: ").append(toIndentedString(id)).append("\n");
    sb.append("    version: ").append(toIndentedString(version)).append("\n");
    sb.append("    description: ").append(toIndentedString(description))
        .append("\n");
    sb.append("    artifact: ").append(toIndentedString(artifact)).append("\n");
    sb.append("    resource: ").append(toIndentedString(resource)).append("\n");
    sb.append("    launchTime: ").append(toIndentedString(launchTime))
        .append("\n");
    sb.append("    numberOfRunningContainers: ")
        .append(toIndentedString(numberOfRunningContainers)).append("\n");
    sb.append("    lifetime: ").append(toIndentedString(lifetime)).append("\n");
    sb.append("    components: ").append(toIndentedString(components))
        .append("\n");
    sb.append("    configuration: ").append(toIndentedString(configuration))
        .append("\n");
    sb.append("    state: ").append(toIndentedString(state)).append("\n");
    sb.append("    quicklinks: ").append(toIndentedString(quicklinks))
        .append("\n");
    sb.append("    queue: ").append(toIndentedString(queue)).append("\n");
    sb.append("    kerberosPrincipal: ")
        .append(toIndentedString(kerberosPrincipal)).append("\n");
    sb.append("    dockerClientConfig: ")
        .append(toIndentedString(dockerClientConfig)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(java.lang.Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}
