// This file is @generated
{% set class_ty = type.name | to_upper_camel_case -%}
package com.svix.models;

import com.svix.MaybeUnset;
import com.svix.MaybeUnsetSerializer;
import com.svix.Utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonProcessingException;

import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.Optional;
import java.util.HashMap;
import java.time.OffsetDateTime;
import java.util.LinkedHashSet;
import java.util.ArrayList;
import java.net.URI;
import java.util.Objects;

import lombok.EqualsAndHashCode;
import lombok.ToString;

@ToString
@EqualsAndHashCode
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonAutoDetect(getterVisibility = Visibility.NONE,setterVisibility = Visibility.NONE)
public class {{ type.name | to_upper_camel_case }} {
{% for field in type.fields -%}
    {% set field_ty = field.type.to_java() -%}
    {% set field_annotation = "" -%}

    {# ensure json field name is correct -#}
    {% if field.name != field.name | to_lower_camel_case -%}
        {% set field_annotation %}@JsonProperty("{{ field.name }}"){% endset -%}
    {% else -%}
    {% set field_annotation %}@JsonProperty{% endset -%}
    {% endif -%}

    {# none nullable fields -#}
    {% if type.name is endingwith "Patch" and field.nullable -%}
        {% set field_ty %}MaybeUnset<{{ field_ty }}>{% endset -%}
    {% endif -%}
    {% if type.name == "MessageIn" and field.name == "payload" -%}
        {% set field_ty = "String" -%}
    {% elif type.name == "MessageIn" and field.name == "transformationsParams" -%}
        {% set field_ty = "Map<String, Object>" -%}
    {% endif -%}
    {{ field_annotation}} private {{ field_ty }} {{ field.name | to_lower_camel_case }};
{% endfor -%}

  public {{ type.name | to_upper_camel_case }} () {}


{% for field in type.fields -%}
    {% set f_ty = field.type.to_java() -%}
    {% if type.name == "MessageIn" and field.name == "payload" -%}
        {% set f_ty = "String" -%}
    {% elif type.name == "MessageIn" and field.name == "transformationsParams" -%}
        {% set f_ty = "Map<String, Object>" -%}
    {% endif -%}
    {% set f_varname = field.name | to_lower_camel_case -%}
    {% set f_deprecated = "" -%}
    {% if field.deprecated -%}
        {% set f_deprecated = "@Deprecated" -%}
    {% endif -%}


    {{ f_deprecated }} public {{ class_ty }} {{ f_varname }}({{ f_ty }} {{ f_varname }}) {
        {% if type.name is endingwith "Patch" and field.nullable -%}
        this.{{ f_varname }} = new MaybeUnset<>({{ f_varname }});
        {% else -%}
        this.{{ f_varname }} = {{ f_varname }};
        {% endif -%}
        return this;
    }

    {% if field.type.is_set() or field.type.is_list() -%}
    {{ f_deprecated }} public {{ class_ty }} add{{ f_varname | to_upper_camel_case }}Item(
        {{ field.type.inner_type().to_java() }} {{ f_varname }}Item
    ) {
        if (this.{{ f_varname }} == null) {
            {% if field.type.is_set() -%}
                {% set init_expr = "new LinkedHashSet<>()" -%}
            {% else -%}
                {% set init_expr = "new ArrayList<>()" -%}
            {% endif -%}
            {% if type.name is endingwith "Patch" and field.nullable -%}
                {% set init_expr %}new MaybeUnset<>({{ init_expr }}){% endset -%}
            {% endif -%}

            this.{{ f_varname }} = {{ init_expr }};
        }
        {% if type.name is endingwith "Patch" and field.nullable -%}
        this.{{ f_varname }}.getValue().add({{ f_varname }}Item);
        {% else -%}
        this.{{ f_varname }}.add({{ f_varname }}Item);
        {% endif %}
        return this;
    }
    {% elif field.type.is_map() -%}
    {{ f_deprecated }} public {{ class_ty }} put{{ f_varname | to_upper_camel_case }}Item(String key, String {{ f_varname }}Item) {
        if (this.{{ f_varname }} == null) {
            {% if type.name is endingwith "Patch" and field.nullable -%}
            this.{{ f_varname }} = new MaybeUnset<>(new HashMap<>());
            {% else -%}
            this.{{ f_varname }} = new HashMap<>();
            {% endif -%}
        }
        {% if type.name is endingwith "Patch" and field.nullable -%}
        this.{{ f_varname }}.getValue().put(key, {{ f_varname }}Item);
        {% else -%}
        this.{{ f_varname }}.put(key, {{ f_varname }}Item);
        {% endif %}
        return this;
    }
    {% endif -%}

    /**
    {% if field.description is defined -%}
     * {{ field.description }}
    {% else -%}
     * Get {{ f_varname }}
    {% endif -%}
     *
     * @return {{ f_varname }}
     */
    {% if field.nullable or not field.required -%}
    @javax.annotation.Nullable
    {% else -%}
    @javax.annotation.Nonnull
    {% endif -%}
    {{ f_deprecated }} public {{ f_ty }} get{{ f_varname | to_upper_camel_case }}() {
        {% if type.name is endingwith "Patch" and field.nullable -%}
        if ({{ f_varname }} == null){
            return null;
        }
        return {{ f_varname }}.getValue();
        {% else -%}
        return {{ f_varname }};
        {% endif -%}
    }

    {{ f_deprecated }} public void set{{ f_varname | to_upper_camel_case }}({{ f_ty }} {{ f_varname }}) {
        {% if type.name is endingwith "Patch" and field.nullable -%}
        this.{{ f_varname }} = new MaybeUnset<>({{ f_varname }});
        {% else -%}
        this.{{ f_varname }} = {{ f_varname }};
        {% endif -%}

    }
    {% if field.type.is_string_const() -%}
    {# This field has the type of ClassType.TypeEnum (backwards compat) #}
    public enum TypeEnum {
        {{ field.type.string_const_val() | to_upper_snake_case }}("{{ field.type.string_const_val() }}");
        private final String value;

        TypeEnum(String value) {
            this.value = value;
        }

        @JsonValue
        public String getValue() {
            return this.value;
        }
        @Override
        public String toString(){
            return this.value;
        }
        public static TypeEnum fromValue(String value) {
            if (!Objects.equals(value, "{{ field.type.string_const_val() }}")){
                throw new IllegalArgumentException("Unexpected value '" + value + "'");
            }
            return {{ field.type.string_const_val() | to_upper_snake_case }};
        }

    }
    {% endif -%}
{% endfor -%}
    /**
     * Create an instance of {{ class_ty }} given an JSON string
     *
     * @param jsonString JSON string
     * @return An instance of {{ class_ty }}
     * @throws JsonProcessingException if the JSON string is invalid with respect to {{ class_ty }}
     */
    public static {{ class_ty }} fromJson(String jsonString) throws JsonProcessingException {
        return Utils.getObjectMapper().readValue(jsonString, {{ class_ty }}.class);
    }

    /**
     * Convert an instance of {{ class_ty }} to an JSON string
     *
     * @return JSON string
     */
    public String toJson() throws JsonProcessingException {
        return Utils.getObjectMapper().writeValueAsString(this);
    }
}
