import io.swagger.annotations.*;
{{#useBeanValidation}}import jakarta.validation.Valid;{{/useBeanValidation}}
{{#additionalPropertiesType}}
import com.fasterxml.jackson.annotation.JsonValue;
{{/additionalPropertiesType}}
{{!
Note that this template is copied /modified from
https://github.com/OpenAPITools/openapi-generator/blob/640ef9d9448a4a008af90eca9cc84c8a78ec87ec/modules/openapi-generator/src/main/resources/JavaJaxRS/resteasy/pojo.mustache
It is updated to remove all swagger annotations and support builders and immutability
}}

{{#description}}@ApiModel(description="{{{.}}}"){{/description}}{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{#vendorExtensions.x-class-extra-annotation}}
    {{{vendorExtensions.x-class-extra-annotation}}}
{{/vendorExtensions.x-class-extra-annotation}}public class {{classname}} {{#parent}}extends {{{.}}}{{/parent}} {{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
{{#serializableModel}}
    private static final long serialVersionUID = 1L;
{{/serializableModel}}
{{#vars}}{{#isEnum}}{{^isContainer}}
    {{>enumClass}}{{/isContainer}}{{#isContainer}}{{#mostInnerItems}}
    {{>enumClass}}{{/mostInnerItems}}{{/isContainer}}{{/isEnum}}
{{#vendorExtensions.x-field-extra-annotation}}
    {{{vendorExtensions.x-field-extra-annotation}}}
{{/vendorExtensions.x-field-extra-annotation}}
{{#useBeanValidation}}{{>beanValidation}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime}}{{^isString}}{{^isFile}}  @Valid
{{/isFile}}{{/isString}}{{/isDateTime}}{{/isDate}}{{/isPrimitiveType}}{{/useBeanValidation}}  private final {{{datatypeWithEnum}}} {{name}};{{/vars}}
{{#vars}}
    /**
    {{#description}}
     * {{.}}
    {{/description}}
    {{#minimum}}
     * minimum: {{.}}
    {{/minimum}}
    {{#maximum}}
     * maximum: {{.}}
    {{/maximum}}
     **/
    {{#vendorExtensions.x-extra-annotation}}{{{vendorExtensions.x-extra-annotation}}}
    {{/vendorExtensions.x-extra-annotation}}@ApiModelProperty({{#example}}example = "{{{.}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
    @JsonProperty(value = "{{baseName}}"{{#required}}, required = true{{/required}})
    public {{{datatypeWithEnum}}} {{getter}}() {
        return {{name}};
    }
    
{{/vars}}
    {{#vendorExtensions.x-java-all-args-constructor}}
    @JsonCreator
    public {{classname}}({{#vendorExtensions.x-java-all-args-constructor-vars}}@JsonProperty(value = "{{baseName}}"{{#required}}, required = true{{/required}}) {{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-java-all-args-constructor-vars}}) {
        {{#parent}}
        super({{#parentVars}}{{name}}{{^-last}}, {{/-last}}{{/parentVars}});
        {{/parent}}
        {{#vars}}
        this.{{name}} = {{#defaultValue}}Objects.requireNonNullElse({{name}}, {{{.}}}){{/defaultValue}}{{^defaultValue}}{{name}}{{/defaultValue}};
        {{/vars}}
    }
    {{/vendorExtensions.x-java-all-args-constructor}}
    {{^vendorExtensions.x-java-all-args-constructor}}
    @JsonCreator
    public {{classname}}({{#allVars}}@JsonProperty("{{baseName}}") {{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}{{/allVars}}) {
        {{#parent}}
        super({{#parentVars}}{{name}}{{^-last}}, {{/-last}}{{/parentVars}});
        {{/parent}}
        {{#vars}}
        this.{{name}} = {{#defaultValue}}Objects.requireNonNullElse({{name}}, {{{.}}}){{/defaultValue}}{{^defaultValue}}{{name}}{{/defaultValue}};
        {{/vars}}
    }
    {{/vendorExtensions.x-java-all-args-constructor}}


    {{#hasOptional}}
    {{#hasRequired}}
    public {{classname}}({{#requiredVars}}{{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}{{/requiredVars}}) {
        {{#parent}}
        super({{#parentRequiredVars}}{{name}}{{^-last}}, {{/-last}}{{/parentRequiredVars}});
        {{/parent}}
        {{#vars}}
        {{#required}}
        this.{{name}} = {{#defaultValue}}Objects.requireNonNullElse({{name}}, {{{.}}}){{/defaultValue}}{{^defaultValue}}{{name}}{{/defaultValue}};
        {{/required}}
        {{^required}}
        this.{{name}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}};
        {{/required}}
        {{/vars}}
    }
    {{/hasRequired}}
    {{/hasOptional}}

    {{^hasChildren}}
    public static Builder builder() {
        return new Builder();
    }
    {{#hasRequired}}
    public static Builder builder({{#requiredVars}}{{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}{{/requiredVars}}) {
        return new Builder({{#requiredVars}}{{name}}{{^-last}}, {{/-last}}{{/requiredVars}});
    }
    {{/hasRequired}}
    {{/hasChildren}}

    {{#additionalPropertiesType}}
    @JsonValue
    public Map<String, {{additionalPropertiesType}}> toMap() {
      Map<String, {{additionalPropertiesType}}> map = new HashMap<>(this);
      {{#vars}}
      map.put("{{baseName}}", {{name}});
      {{/vars}}
      return map;
    }
    {{/additionalPropertiesType}}

    public static final class Builder {
      {{#vendorExtensions.x-java-all-args-constructor}}
      {{#vendorExtensions.x-java-all-args-constructor-vars}}
      private {{{datatypeWithEnum}}} {{name}};
      {{/vendorExtensions.x-java-all-args-constructor-vars}}
      {{/vendorExtensions.x-java-all-args-constructor}}
      {{^vendorExtensions.x-java-all-args-constructor}}
      {{#allVars}}
      private {{{datatypeWithEnum}}} {{name}};
      {{/allVars}}
      {{/vendorExtensions.x-java-all-args-constructor}}
      {{#additionalPropertiesType}}
      private Map<String, {{additionalPropertiesType}}> additionalProperties = new HashMap<>();
      {{/additionalPropertiesType}}
      private Builder() {
      }
      {{#hasRequired}}
      private Builder({{#requiredVars}}{{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}{{/requiredVars}}) {
      {{#requiredVars}}
        this.{{name}} = {{#defaultValue}}Objects.requireNonNullElse({{name}}, {{{.}}}){{/defaultValue}}{{^defaultValue}}{{name}}{{/defaultValue}};
      {{/requiredVars}}
      }
      {{/hasRequired}}

{{#vendorExtensions.x-java-all-args-constructor}}
    {{#vendorExtensions.x-java-all-args-constructor-vars}}
      public Builder {{setter}}({{{datatypeWithEnum}}} {{name}}) {
        this.{{name}} = {{name}};
        return this;
      }
    {{/vendorExtensions.x-java-all-args-constructor-vars}}
{{/vendorExtensions.x-java-all-args-constructor}}
{{^vendorExtensions.x-java-all-args-constructor}}
    {{#allVars}}
      public Builder {{setter}}({{{datatypeWithEnum}}} {{name}}) {
        this.{{name}} = {{name}};
        return this;
      }
    {{/allVars}}
{{/vendorExtensions.x-java-all-args-constructor}}
{{#additionalPropertiesType}}
      public Builder addProperty(String key, {{additionalPropertiesType}} value) {
        additionalProperties.put(key, value);
        return this;
      }

      public Builder putAll(Map<String, {{additionalPropertiesType}}> values) {
        additionalProperties.putAll(values);
        return this;
      }
{{/additionalPropertiesType}}


      public {{classname}} build() {
{{#vendorExtensions.x-java-all-args-constructor}}
        {{classname}} inst = new {{classname}}({{#vendorExtensions.x-java-all-args-constructor-vars}}{{name}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-java-all-args-constructor-vars}});
        {{#additionalPropertiesType}}
        inst.putAll(additionalProperties);
        {{/additionalPropertiesType}}
        return inst;
{{/vendorExtensions.x-java-all-args-constructor}}
{{^vendorExtensions.x-java-all-args-constructor}}
        {{classname}} inst = new {{classname}}({{#allVars}}{{name}}{{^-last}}, {{/-last}}{{/allVars}});
        {{#additionalPropertiesType}}
        inst.putAll(additionalProperties);
        {{/additionalPropertiesType}}
        return inst;
{{/vendorExtensions.x-java-all-args-constructor}}
      }
    }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    {{classname}} {{classVarName}} = ({{classname}}) o;{{#hasVars}}
    return {{#parent}}super.equals(o) && {{/parent}}{{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{^-last}} &&
        {{/-last}}{{#-last}};{{/-last}}{{/vars}}{{/hasVars}}{{^hasVars}}{{#parent}}return super.equals(o);{{/parent}}{{^parent}}return true;{{/parent}}{{/hasVars}}
  }

  @Override
  public int hashCode() {
    return {{^hasVars}}{{#parent}}super.hashCode(){{/parent}}{{^parent}}1{{/parent}}{{/hasVars}}{{#hasVars}}Objects.hash({{#vars}}{{#parent}}super.hashCode(), {{/parent}}{{name}}{{^-last}}, {{/-last}}{{/vars}}){{/hasVars}};
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class {{classname}} {\n");
    {{#parent}}sb.append("    ").append(toIndentedString(super.toString())).append("\n");{{/parent}}
    {{#vars}}sb.append("    {{name}}: ").append({{#isPassword}}"*"{{/isPassword}}{{^isPassword}}toIndentedString({{name}}){{/isPassword}}).append("\n");
    {{/vars}}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(Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}