package {{ root_package }}.extensions.{{ extension }}.types;

import {{ root_package }}.internal.JsonSupport;
import {{ root_package }}.internal.WireSerializable;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

public final class Hstore implements WireSerializable {
    private final JsonSupport.Hstore value;

    public Hstore(Map<String, String> value) {
        this.value = new JsonSupport.Hstore(value);
    }

    public static Hstore of(Map<String, String> value) {
        return new Hstore(value);
    }

    @SafeVarargs
    public static Hstore ofEntries(Map.Entry<String, String>... entries) {
        LinkedHashMap<String, String> values = new LinkedHashMap<>();
        if (entries != null) {
            for (Map.Entry<String, String> entry : entries) {
                if (entry != null) {
                    values.put(entry.getKey(), entry.getValue());
                }
            }
        }
        return new Hstore(values);
    }

    public static Hstore empty() {
        return new Hstore(new LinkedHashMap<>());
    }

    public static Hstore fromJsonNode(JsonNode node) {
        JsonSupport.Hstore value = JsonSupport.asHstore(node);
        return value == null ? null : new Hstore(value);
    }

    public Map<String, String> value() {
        return new LinkedHashMap<>(this.value);
    }

    public Map<String, String> asMap() {
        return value();
    }

    public String get(String key) {
        return this.value.get(key);
    }

    public boolean containsKey(String key) {
        return this.value.containsKey(key);
    }

    public int size() {
        return this.value.size();
    }

    public boolean isEmpty() {
        return this.value.isEmpty();
    }

    public Hstore with(String key, String value) {
        LinkedHashMap<String, String> next = new LinkedHashMap<>(this.value);
        next.put(key, value);
        return new Hstore(next);
    }

    public Hstore withNull(String key) {
        return with(key, null);
    }

    public JsonSupport.Hstore toWire() {
        return new JsonSupport.Hstore(this.value);
    }

    public boolean equals(Map<String, String> other) {
        return Objects.equals(this.value, other);
    }

    @Override
    public JsonNode toJsonNode() {
        return JsonSupport.toJsonNode(this.value);
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (other instanceof Hstore typed) {
            return Objects.equals(this.value, typed.value);
        }
        if (other instanceof Map<?, ?> raw) {
            return Objects.equals(this.value, raw);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(this.value);
    }

    @Override
    public String toString() {
        return this.value.toString();
    }
}
