/* 
 * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
 */

package dev.plexapi.sdk.models.operations;


import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import dev.plexapi.sdk.utils.Utils;
import java.lang.Boolean;
import java.lang.Long;
import java.lang.Override;
import java.lang.String;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;


public class PlexDevice {

    @JsonProperty("name")
    private String name;

    @JsonProperty("product")
    private String product;

    @JsonProperty("productVersion")
    private String productVersion;

    @JsonInclude(Include.ALWAYS)
    @JsonProperty("platform")
    private Optional<String> platform;

    @JsonInclude(Include.ALWAYS)
    @JsonProperty("platformVersion")
    private Optional<String> platformVersion;

    @JsonInclude(Include.ALWAYS)
    @JsonProperty("device")
    private Optional<String> device;

    @JsonProperty("clientIdentifier")
    private String clientIdentifier;

    @JsonProperty("createdAt")
    private OffsetDateTime createdAt;

    @JsonProperty("lastSeenAt")
    private OffsetDateTime lastSeenAt;

    @JsonProperty("provides")
    private String provides;

    /**
     * ownerId is null when the device is owned by the token used to send the request
     */
    @JsonInclude(Include.ALWAYS)
    @JsonProperty("ownerId")
    private Optional<Long> ownerId;

    @JsonInclude(Include.ALWAYS)
    @JsonProperty("sourceTitle")
    private Optional<String> sourceTitle;

    @JsonProperty("publicAddress")
    private String publicAddress;

    @JsonProperty("accessToken")
    private String accessToken;

    @JsonProperty("owned")
    private boolean owned;

    @JsonProperty("home")
    private boolean home;

    @JsonProperty("synced")
    private boolean synced;

    @JsonProperty("relay")
    private boolean relay;

    @JsonProperty("presence")
    private boolean presence;

    @JsonProperty("httpsRequired")
    private boolean httpsRequired;

    @JsonProperty("publicAddressMatches")
    private boolean publicAddressMatches;

    @JsonProperty("dnsRebindingProtection")
    private boolean dnsRebindingProtection;

    @JsonProperty("natLoopbackSupported")
    private boolean natLoopbackSupported;

    @JsonProperty("connections")
    private List<Connections> connections;

    @JsonCreator
    public PlexDevice(
            @JsonProperty("name") String name,
            @JsonProperty("product") String product,
            @JsonProperty("productVersion") String productVersion,
            @JsonProperty("platform") Optional<String> platform,
            @JsonProperty("platformVersion") Optional<String> platformVersion,
            @JsonProperty("device") Optional<String> device,
            @JsonProperty("clientIdentifier") String clientIdentifier,
            @JsonProperty("createdAt") OffsetDateTime createdAt,
            @JsonProperty("lastSeenAt") OffsetDateTime lastSeenAt,
            @JsonProperty("provides") String provides,
            @JsonProperty("ownerId") Optional<Long> ownerId,
            @JsonProperty("sourceTitle") Optional<String> sourceTitle,
            @JsonProperty("publicAddress") String publicAddress,
            @JsonProperty("accessToken") String accessToken,
            @JsonProperty("owned") boolean owned,
            @JsonProperty("home") boolean home,
            @JsonProperty("synced") boolean synced,
            @JsonProperty("relay") boolean relay,
            @JsonProperty("presence") boolean presence,
            @JsonProperty("httpsRequired") boolean httpsRequired,
            @JsonProperty("publicAddressMatches") boolean publicAddressMatches,
            @JsonProperty("dnsRebindingProtection") boolean dnsRebindingProtection,
            @JsonProperty("natLoopbackSupported") boolean natLoopbackSupported,
            @JsonProperty("connections") List<Connections> connections) {
        Utils.checkNotNull(name, "name");
        Utils.checkNotNull(product, "product");
        Utils.checkNotNull(productVersion, "productVersion");
        Utils.checkNotNull(platform, "platform");
        Utils.checkNotNull(platformVersion, "platformVersion");
        Utils.checkNotNull(device, "device");
        Utils.checkNotNull(clientIdentifier, "clientIdentifier");
        Utils.checkNotNull(createdAt, "createdAt");
        Utils.checkNotNull(lastSeenAt, "lastSeenAt");
        Utils.checkNotNull(provides, "provides");
        Utils.checkNotNull(ownerId, "ownerId");
        Utils.checkNotNull(sourceTitle, "sourceTitle");
        Utils.checkNotNull(publicAddress, "publicAddress");
        Utils.checkNotNull(accessToken, "accessToken");
        Utils.checkNotNull(owned, "owned");
        Utils.checkNotNull(home, "home");
        Utils.checkNotNull(synced, "synced");
        Utils.checkNotNull(relay, "relay");
        Utils.checkNotNull(presence, "presence");
        Utils.checkNotNull(httpsRequired, "httpsRequired");
        Utils.checkNotNull(publicAddressMatches, "publicAddressMatches");
        Utils.checkNotNull(dnsRebindingProtection, "dnsRebindingProtection");
        Utils.checkNotNull(natLoopbackSupported, "natLoopbackSupported");
        Utils.checkNotNull(connections, "connections");
        this.name = name;
        this.product = product;
        this.productVersion = productVersion;
        this.platform = platform;
        this.platformVersion = platformVersion;
        this.device = device;
        this.clientIdentifier = clientIdentifier;
        this.createdAt = createdAt;
        this.lastSeenAt = lastSeenAt;
        this.provides = provides;
        this.ownerId = ownerId;
        this.sourceTitle = sourceTitle;
        this.publicAddress = publicAddress;
        this.accessToken = accessToken;
        this.owned = owned;
        this.home = home;
        this.synced = synced;
        this.relay = relay;
        this.presence = presence;
        this.httpsRequired = httpsRequired;
        this.publicAddressMatches = publicAddressMatches;
        this.dnsRebindingProtection = dnsRebindingProtection;
        this.natLoopbackSupported = natLoopbackSupported;
        this.connections = connections;
    }
    
    public PlexDevice(
            String name,
            String product,
            String productVersion,
            String clientIdentifier,
            OffsetDateTime createdAt,
            OffsetDateTime lastSeenAt,
            String provides,
            String publicAddress,
            String accessToken,
            boolean owned,
            boolean home,
            boolean synced,
            boolean relay,
            boolean presence,
            boolean httpsRequired,
            boolean publicAddressMatches,
            boolean dnsRebindingProtection,
            boolean natLoopbackSupported,
            List<Connections> connections) {
        this(name, product, productVersion, Optional.empty(), Optional.empty(), Optional.empty(), clientIdentifier, createdAt, lastSeenAt, provides, Optional.empty(), Optional.empty(), publicAddress, accessToken, owned, home, synced, relay, presence, httpsRequired, publicAddressMatches, dnsRebindingProtection, natLoopbackSupported, connections);
    }

    @JsonIgnore
    public String name() {
        return name;
    }

    @JsonIgnore
    public String product() {
        return product;
    }

    @JsonIgnore
    public String productVersion() {
        return productVersion;
    }

    @JsonIgnore
    public Optional<String> platform() {
        return platform;
    }

    @JsonIgnore
    public Optional<String> platformVersion() {
        return platformVersion;
    }

    @JsonIgnore
    public Optional<String> device() {
        return device;
    }

    @JsonIgnore
    public String clientIdentifier() {
        return clientIdentifier;
    }

    @JsonIgnore
    public OffsetDateTime createdAt() {
        return createdAt;
    }

    @JsonIgnore
    public OffsetDateTime lastSeenAt() {
        return lastSeenAt;
    }

    @JsonIgnore
    public String provides() {
        return provides;
    }

    /**
     * ownerId is null when the device is owned by the token used to send the request
     */
    @JsonIgnore
    public Optional<Long> ownerId() {
        return ownerId;
    }

    @JsonIgnore
    public Optional<String> sourceTitle() {
        return sourceTitle;
    }

    @JsonIgnore
    public String publicAddress() {
        return publicAddress;
    }

    @JsonIgnore
    public String accessToken() {
        return accessToken;
    }

    @JsonIgnore
    public boolean owned() {
        return owned;
    }

    @JsonIgnore
    public boolean home() {
        return home;
    }

    @JsonIgnore
    public boolean synced() {
        return synced;
    }

    @JsonIgnore
    public boolean relay() {
        return relay;
    }

    @JsonIgnore
    public boolean presence() {
        return presence;
    }

    @JsonIgnore
    public boolean httpsRequired() {
        return httpsRequired;
    }

    @JsonIgnore
    public boolean publicAddressMatches() {
        return publicAddressMatches;
    }

    @JsonIgnore
    public boolean dnsRebindingProtection() {
        return dnsRebindingProtection;
    }

    @JsonIgnore
    public boolean natLoopbackSupported() {
        return natLoopbackSupported;
    }

    @JsonIgnore
    public List<Connections> connections() {
        return connections;
    }

    public final static Builder builder() {
        return new Builder();
    }

    public PlexDevice withName(String name) {
        Utils.checkNotNull(name, "name");
        this.name = name;
        return this;
    }

    public PlexDevice withProduct(String product) {
        Utils.checkNotNull(product, "product");
        this.product = product;
        return this;
    }

    public PlexDevice withProductVersion(String productVersion) {
        Utils.checkNotNull(productVersion, "productVersion");
        this.productVersion = productVersion;
        return this;
    }

    public PlexDevice withPlatform(String platform) {
        Utils.checkNotNull(platform, "platform");
        this.platform = Optional.ofNullable(platform);
        return this;
    }

    public PlexDevice withPlatform(Optional<String> platform) {
        Utils.checkNotNull(platform, "platform");
        this.platform = platform;
        return this;
    }

    public PlexDevice withPlatformVersion(String platformVersion) {
        Utils.checkNotNull(platformVersion, "platformVersion");
        this.platformVersion = Optional.ofNullable(platformVersion);
        return this;
    }

    public PlexDevice withPlatformVersion(Optional<String> platformVersion) {
        Utils.checkNotNull(platformVersion, "platformVersion");
        this.platformVersion = platformVersion;
        return this;
    }

    public PlexDevice withDevice(String device) {
        Utils.checkNotNull(device, "device");
        this.device = Optional.ofNullable(device);
        return this;
    }

    public PlexDevice withDevice(Optional<String> device) {
        Utils.checkNotNull(device, "device");
        this.device = device;
        return this;
    }

    public PlexDevice withClientIdentifier(String clientIdentifier) {
        Utils.checkNotNull(clientIdentifier, "clientIdentifier");
        this.clientIdentifier = clientIdentifier;
        return this;
    }

    public PlexDevice withCreatedAt(OffsetDateTime createdAt) {
        Utils.checkNotNull(createdAt, "createdAt");
        this.createdAt = createdAt;
        return this;
    }

    public PlexDevice withLastSeenAt(OffsetDateTime lastSeenAt) {
        Utils.checkNotNull(lastSeenAt, "lastSeenAt");
        this.lastSeenAt = lastSeenAt;
        return this;
    }

    public PlexDevice withProvides(String provides) {
        Utils.checkNotNull(provides, "provides");
        this.provides = provides;
        return this;
    }

    /**
     * ownerId is null when the device is owned by the token used to send the request
     */
    public PlexDevice withOwnerId(long ownerId) {
        Utils.checkNotNull(ownerId, "ownerId");
        this.ownerId = Optional.ofNullable(ownerId);
        return this;
    }

    /**
     * ownerId is null when the device is owned by the token used to send the request
     */
    public PlexDevice withOwnerId(Optional<Long> ownerId) {
        Utils.checkNotNull(ownerId, "ownerId");
        this.ownerId = ownerId;
        return this;
    }

    public PlexDevice withSourceTitle(String sourceTitle) {
        Utils.checkNotNull(sourceTitle, "sourceTitle");
        this.sourceTitle = Optional.ofNullable(sourceTitle);
        return this;
    }

    public PlexDevice withSourceTitle(Optional<String> sourceTitle) {
        Utils.checkNotNull(sourceTitle, "sourceTitle");
        this.sourceTitle = sourceTitle;
        return this;
    }

    public PlexDevice withPublicAddress(String publicAddress) {
        Utils.checkNotNull(publicAddress, "publicAddress");
        this.publicAddress = publicAddress;
        return this;
    }

    public PlexDevice withAccessToken(String accessToken) {
        Utils.checkNotNull(accessToken, "accessToken");
        this.accessToken = accessToken;
        return this;
    }

    public PlexDevice withOwned(boolean owned) {
        Utils.checkNotNull(owned, "owned");
        this.owned = owned;
        return this;
    }

    public PlexDevice withHome(boolean home) {
        Utils.checkNotNull(home, "home");
        this.home = home;
        return this;
    }

    public PlexDevice withSynced(boolean synced) {
        Utils.checkNotNull(synced, "synced");
        this.synced = synced;
        return this;
    }

    public PlexDevice withRelay(boolean relay) {
        Utils.checkNotNull(relay, "relay");
        this.relay = relay;
        return this;
    }

    public PlexDevice withPresence(boolean presence) {
        Utils.checkNotNull(presence, "presence");
        this.presence = presence;
        return this;
    }

    public PlexDevice withHttpsRequired(boolean httpsRequired) {
        Utils.checkNotNull(httpsRequired, "httpsRequired");
        this.httpsRequired = httpsRequired;
        return this;
    }

    public PlexDevice withPublicAddressMatches(boolean publicAddressMatches) {
        Utils.checkNotNull(publicAddressMatches, "publicAddressMatches");
        this.publicAddressMatches = publicAddressMatches;
        return this;
    }

    public PlexDevice withDnsRebindingProtection(boolean dnsRebindingProtection) {
        Utils.checkNotNull(dnsRebindingProtection, "dnsRebindingProtection");
        this.dnsRebindingProtection = dnsRebindingProtection;
        return this;
    }

    public PlexDevice withNatLoopbackSupported(boolean natLoopbackSupported) {
        Utils.checkNotNull(natLoopbackSupported, "natLoopbackSupported");
        this.natLoopbackSupported = natLoopbackSupported;
        return this;
    }

    public PlexDevice withConnections(List<Connections> connections) {
        Utils.checkNotNull(connections, "connections");
        this.connections = connections;
        return this;
    }
    
    @Override
    public boolean equals(java.lang.Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        PlexDevice other = (PlexDevice) o;
        return 
            Objects.deepEquals(this.name, other.name) &&
            Objects.deepEquals(this.product, other.product) &&
            Objects.deepEquals(this.productVersion, other.productVersion) &&
            Objects.deepEquals(this.platform, other.platform) &&
            Objects.deepEquals(this.platformVersion, other.platformVersion) &&
            Objects.deepEquals(this.device, other.device) &&
            Objects.deepEquals(this.clientIdentifier, other.clientIdentifier) &&
            Objects.deepEquals(this.createdAt, other.createdAt) &&
            Objects.deepEquals(this.lastSeenAt, other.lastSeenAt) &&
            Objects.deepEquals(this.provides, other.provides) &&
            Objects.deepEquals(this.ownerId, other.ownerId) &&
            Objects.deepEquals(this.sourceTitle, other.sourceTitle) &&
            Objects.deepEquals(this.publicAddress, other.publicAddress) &&
            Objects.deepEquals(this.accessToken, other.accessToken) &&
            Objects.deepEquals(this.owned, other.owned) &&
            Objects.deepEquals(this.home, other.home) &&
            Objects.deepEquals(this.synced, other.synced) &&
            Objects.deepEquals(this.relay, other.relay) &&
            Objects.deepEquals(this.presence, other.presence) &&
            Objects.deepEquals(this.httpsRequired, other.httpsRequired) &&
            Objects.deepEquals(this.publicAddressMatches, other.publicAddressMatches) &&
            Objects.deepEquals(this.dnsRebindingProtection, other.dnsRebindingProtection) &&
            Objects.deepEquals(this.natLoopbackSupported, other.natLoopbackSupported) &&
            Objects.deepEquals(this.connections, other.connections);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(
            name,
            product,
            productVersion,
            platform,
            platformVersion,
            device,
            clientIdentifier,
            createdAt,
            lastSeenAt,
            provides,
            ownerId,
            sourceTitle,
            publicAddress,
            accessToken,
            owned,
            home,
            synced,
            relay,
            presence,
            httpsRequired,
            publicAddressMatches,
            dnsRebindingProtection,
            natLoopbackSupported,
            connections);
    }
    
    @Override
    public String toString() {
        return Utils.toString(PlexDevice.class,
                "name", name,
                "product", product,
                "productVersion", productVersion,
                "platform", platform,
                "platformVersion", platformVersion,
                "device", device,
                "clientIdentifier", clientIdentifier,
                "createdAt", createdAt,
                "lastSeenAt", lastSeenAt,
                "provides", provides,
                "ownerId", ownerId,
                "sourceTitle", sourceTitle,
                "publicAddress", publicAddress,
                "accessToken", accessToken,
                "owned", owned,
                "home", home,
                "synced", synced,
                "relay", relay,
                "presence", presence,
                "httpsRequired", httpsRequired,
                "publicAddressMatches", publicAddressMatches,
                "dnsRebindingProtection", dnsRebindingProtection,
                "natLoopbackSupported", natLoopbackSupported,
                "connections", connections);
    }
    
    public final static class Builder {
 
        private String name;
 
        private String product;
 
        private String productVersion;
 
        private Optional<String> platform = Optional.empty();
 
        private Optional<String> platformVersion = Optional.empty();
 
        private Optional<String> device = Optional.empty();
 
        private String clientIdentifier;
 
        private OffsetDateTime createdAt;
 
        private OffsetDateTime lastSeenAt;
 
        private String provides;
 
        private Optional<Long> ownerId = Optional.empty();
 
        private Optional<String> sourceTitle = Optional.empty();
 
        private String publicAddress;
 
        private String accessToken;
 
        private Boolean owned;
 
        private Boolean home;
 
        private Boolean synced;
 
        private Boolean relay;
 
        private Boolean presence;
 
        private Boolean httpsRequired;
 
        private Boolean publicAddressMatches;
 
        private Boolean dnsRebindingProtection;
 
        private Boolean natLoopbackSupported;
 
        private List<Connections> connections;  
        
        private Builder() {
          // force use of static builder() method
        }

        public Builder name(String name) {
            Utils.checkNotNull(name, "name");
            this.name = name;
            return this;
        }

        public Builder product(String product) {
            Utils.checkNotNull(product, "product");
            this.product = product;
            return this;
        }

        public Builder productVersion(String productVersion) {
            Utils.checkNotNull(productVersion, "productVersion");
            this.productVersion = productVersion;
            return this;
        }

        public Builder platform(String platform) {
            Utils.checkNotNull(platform, "platform");
            this.platform = Optional.ofNullable(platform);
            return this;
        }

        public Builder platform(Optional<String> platform) {
            Utils.checkNotNull(platform, "platform");
            this.platform = platform;
            return this;
        }

        public Builder platformVersion(String platformVersion) {
            Utils.checkNotNull(platformVersion, "platformVersion");
            this.platformVersion = Optional.ofNullable(platformVersion);
            return this;
        }

        public Builder platformVersion(Optional<String> platformVersion) {
            Utils.checkNotNull(platformVersion, "platformVersion");
            this.platformVersion = platformVersion;
            return this;
        }

        public Builder device(String device) {
            Utils.checkNotNull(device, "device");
            this.device = Optional.ofNullable(device);
            return this;
        }

        public Builder device(Optional<String> device) {
            Utils.checkNotNull(device, "device");
            this.device = device;
            return this;
        }

        public Builder clientIdentifier(String clientIdentifier) {
            Utils.checkNotNull(clientIdentifier, "clientIdentifier");
            this.clientIdentifier = clientIdentifier;
            return this;
        }

        public Builder createdAt(OffsetDateTime createdAt) {
            Utils.checkNotNull(createdAt, "createdAt");
            this.createdAt = createdAt;
            return this;
        }

        public Builder lastSeenAt(OffsetDateTime lastSeenAt) {
            Utils.checkNotNull(lastSeenAt, "lastSeenAt");
            this.lastSeenAt = lastSeenAt;
            return this;
        }

        public Builder provides(String provides) {
            Utils.checkNotNull(provides, "provides");
            this.provides = provides;
            return this;
        }

        /**
         * ownerId is null when the device is owned by the token used to send the request
         */
        public Builder ownerId(long ownerId) {
            Utils.checkNotNull(ownerId, "ownerId");
            this.ownerId = Optional.ofNullable(ownerId);
            return this;
        }

        /**
         * ownerId is null when the device is owned by the token used to send the request
         */
        public Builder ownerId(Optional<Long> ownerId) {
            Utils.checkNotNull(ownerId, "ownerId");
            this.ownerId = ownerId;
            return this;
        }

        public Builder sourceTitle(String sourceTitle) {
            Utils.checkNotNull(sourceTitle, "sourceTitle");
            this.sourceTitle = Optional.ofNullable(sourceTitle);
            return this;
        }

        public Builder sourceTitle(Optional<String> sourceTitle) {
            Utils.checkNotNull(sourceTitle, "sourceTitle");
            this.sourceTitle = sourceTitle;
            return this;
        }

        public Builder publicAddress(String publicAddress) {
            Utils.checkNotNull(publicAddress, "publicAddress");
            this.publicAddress = publicAddress;
            return this;
        }

        public Builder accessToken(String accessToken) {
            Utils.checkNotNull(accessToken, "accessToken");
            this.accessToken = accessToken;
            return this;
        }

        public Builder owned(boolean owned) {
            Utils.checkNotNull(owned, "owned");
            this.owned = owned;
            return this;
        }

        public Builder home(boolean home) {
            Utils.checkNotNull(home, "home");
            this.home = home;
            return this;
        }

        public Builder synced(boolean synced) {
            Utils.checkNotNull(synced, "synced");
            this.synced = synced;
            return this;
        }

        public Builder relay(boolean relay) {
            Utils.checkNotNull(relay, "relay");
            this.relay = relay;
            return this;
        }

        public Builder presence(boolean presence) {
            Utils.checkNotNull(presence, "presence");
            this.presence = presence;
            return this;
        }

        public Builder httpsRequired(boolean httpsRequired) {
            Utils.checkNotNull(httpsRequired, "httpsRequired");
            this.httpsRequired = httpsRequired;
            return this;
        }

        public Builder publicAddressMatches(boolean publicAddressMatches) {
            Utils.checkNotNull(publicAddressMatches, "publicAddressMatches");
            this.publicAddressMatches = publicAddressMatches;
            return this;
        }

        public Builder dnsRebindingProtection(boolean dnsRebindingProtection) {
            Utils.checkNotNull(dnsRebindingProtection, "dnsRebindingProtection");
            this.dnsRebindingProtection = dnsRebindingProtection;
            return this;
        }

        public Builder natLoopbackSupported(boolean natLoopbackSupported) {
            Utils.checkNotNull(natLoopbackSupported, "natLoopbackSupported");
            this.natLoopbackSupported = natLoopbackSupported;
            return this;
        }

        public Builder connections(List<Connections> connections) {
            Utils.checkNotNull(connections, "connections");
            this.connections = connections;
            return this;
        }
        
        public PlexDevice build() {
            return new PlexDevice(
                name,
                product,
                productVersion,
                platform,
                platformVersion,
                device,
                clientIdentifier,
                createdAt,
                lastSeenAt,
                provides,
                ownerId,
                sourceTitle,
                publicAddress,
                accessToken,
                owned,
                home,
                synced,
                relay,
                presence,
                httpsRequired,
                publicAddressMatches,
                dnsRebindingProtection,
                natLoopbackSupported,
                connections);
        }
    }
}

