/* 
 * 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.core.type.TypeReference;
import dev.plexapi.sdk.utils.LazySingletonValue;
import dev.plexapi.sdk.utils.SpeakeasyMetadata;
import dev.plexapi.sdk.utils.Utils;
import java.lang.Integer;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.Objects;
import java.util.Optional;


public class GetWatchListRequest {

    /**
     * Filter
     */
    @SpeakeasyMetadata("pathParam:style=simple,explode=false,name=filter")
    private Filter filter;

    /**
     * In the format "field:dir". Available fields are "watchlistedAt" (Added At),
     * "titleSort" (Title), "originallyAvailableAt" (Release Date), or "rating" (Critic Rating).
     * "dir" can be "asc" or "desc"
     * 
     */
    @SpeakeasyMetadata("queryParam:style=form,explode=true,name=sort")
    private Optional<String> sort;

    /**
     * The type of library to filter. Can be "movie" or "show", or all if not present.
     * 
     */
    @SpeakeasyMetadata("queryParam:style=form,explode=true,name=libtype")
    private Optional<? extends Libtype> libtype;

    /**
     * The number of items to return. If not specified, all items will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * 
     */
    @SpeakeasyMetadata("queryParam:style=form,explode=true,name=maxresults")
    private Optional<Integer> maxresults;

    /**
     * include collections in the results
     * 
     */
    @SpeakeasyMetadata("queryParam:style=form,explode=true,name=includeCollections")
    private Optional<? extends IncludeCollections> includeCollections;

    /**
     * include external media in the results
     * 
     */
    @SpeakeasyMetadata("queryParam:style=form,explode=true,name=includeExternalMedia")
    private Optional<? extends IncludeExternalMedia> includeExternalMedia;

    /**
     * The index of the first item to return. If not specified, the first item will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * By default this is 0
     * 
     */
    @SpeakeasyMetadata("queryParam:style=form,explode=true,name=X-Plex-Container-Start")
    private Optional<Integer> xPlexContainerStart;

    /**
     * The number of items to return. If not specified, all items will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * By default this is 50
     * 
     */
    @SpeakeasyMetadata("queryParam:style=form,explode=true,name=X-Plex-Container-Size")
    private Optional<Integer> xPlexContainerSize;

    /**
     * An authentication token, obtained from plex.tv
     */
    @SpeakeasyMetadata("header:style=simple,explode=false,name=X-Plex-Token")
    private String xPlexToken;

    @JsonCreator
    public GetWatchListRequest(
            Filter filter,
            Optional<String> sort,
            Optional<? extends Libtype> libtype,
            Optional<Integer> maxresults,
            Optional<? extends IncludeCollections> includeCollections,
            Optional<? extends IncludeExternalMedia> includeExternalMedia,
            Optional<Integer> xPlexContainerStart,
            Optional<Integer> xPlexContainerSize,
            String xPlexToken) {
        Utils.checkNotNull(filter, "filter");
        Utils.checkNotNull(sort, "sort");
        Utils.checkNotNull(libtype, "libtype");
        Utils.checkNotNull(maxresults, "maxresults");
        Utils.checkNotNull(includeCollections, "includeCollections");
        Utils.checkNotNull(includeExternalMedia, "includeExternalMedia");
        Utils.checkNotNull(xPlexContainerStart, "xPlexContainerStart");
        Utils.checkNotNull(xPlexContainerSize, "xPlexContainerSize");
        Utils.checkNotNull(xPlexToken, "xPlexToken");
        this.filter = filter;
        this.sort = sort;
        this.libtype = libtype;
        this.maxresults = maxresults;
        this.includeCollections = includeCollections;
        this.includeExternalMedia = includeExternalMedia;
        this.xPlexContainerStart = xPlexContainerStart;
        this.xPlexContainerSize = xPlexContainerSize;
        this.xPlexToken = xPlexToken;
    }
    
    public GetWatchListRequest(
            Filter filter,
            String xPlexToken) {
        this(filter, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), xPlexToken);
    }

    /**
     * Filter
     */
    @JsonIgnore
    public Filter filter() {
        return filter;
    }

    /**
     * In the format "field:dir". Available fields are "watchlistedAt" (Added At),
     * "titleSort" (Title), "originallyAvailableAt" (Release Date), or "rating" (Critic Rating).
     * "dir" can be "asc" or "desc"
     * 
     */
    @JsonIgnore
    public Optional<String> sort() {
        return sort;
    }

    /**
     * The type of library to filter. Can be "movie" or "show", or all if not present.
     * 
     */
    @SuppressWarnings("unchecked")
    @JsonIgnore
    public Optional<Libtype> libtype() {
        return (Optional<Libtype>) libtype;
    }

    /**
     * The number of items to return. If not specified, all items will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * 
     */
    @JsonIgnore
    public Optional<Integer> maxresults() {
        return maxresults;
    }

    /**
     * include collections in the results
     * 
     */
    @SuppressWarnings("unchecked")
    @JsonIgnore
    public Optional<IncludeCollections> includeCollections() {
        return (Optional<IncludeCollections>) includeCollections;
    }

    /**
     * include external media in the results
     * 
     */
    @SuppressWarnings("unchecked")
    @JsonIgnore
    public Optional<IncludeExternalMedia> includeExternalMedia() {
        return (Optional<IncludeExternalMedia>) includeExternalMedia;
    }

    /**
     * The index of the first item to return. If not specified, the first item will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * By default this is 0
     * 
     */
    @JsonIgnore
    public Optional<Integer> xPlexContainerStart() {
        return xPlexContainerStart;
    }

    /**
     * The number of items to return. If not specified, all items will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * By default this is 50
     * 
     */
    @JsonIgnore
    public Optional<Integer> xPlexContainerSize() {
        return xPlexContainerSize;
    }

    /**
     * An authentication token, obtained from plex.tv
     */
    @JsonIgnore
    public String xPlexToken() {
        return xPlexToken;
    }

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

    /**
     * Filter
     */
    public GetWatchListRequest withFilter(Filter filter) {
        Utils.checkNotNull(filter, "filter");
        this.filter = filter;
        return this;
    }

    /**
     * In the format "field:dir". Available fields are "watchlistedAt" (Added At),
     * "titleSort" (Title), "originallyAvailableAt" (Release Date), or "rating" (Critic Rating).
     * "dir" can be "asc" or "desc"
     * 
     */
    public GetWatchListRequest withSort(String sort) {
        Utils.checkNotNull(sort, "sort");
        this.sort = Optional.ofNullable(sort);
        return this;
    }

    /**
     * In the format "field:dir". Available fields are "watchlistedAt" (Added At),
     * "titleSort" (Title), "originallyAvailableAt" (Release Date), or "rating" (Critic Rating).
     * "dir" can be "asc" or "desc"
     * 
     */
    public GetWatchListRequest withSort(Optional<String> sort) {
        Utils.checkNotNull(sort, "sort");
        this.sort = sort;
        return this;
    }

    /**
     * The type of library to filter. Can be "movie" or "show", or all if not present.
     * 
     */
    public GetWatchListRequest withLibtype(Libtype libtype) {
        Utils.checkNotNull(libtype, "libtype");
        this.libtype = Optional.ofNullable(libtype);
        return this;
    }

    /**
     * The type of library to filter. Can be "movie" or "show", or all if not present.
     * 
     */
    public GetWatchListRequest withLibtype(Optional<? extends Libtype> libtype) {
        Utils.checkNotNull(libtype, "libtype");
        this.libtype = libtype;
        return this;
    }

    /**
     * The number of items to return. If not specified, all items will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * 
     */
    public GetWatchListRequest withMaxresults(int maxresults) {
        Utils.checkNotNull(maxresults, "maxresults");
        this.maxresults = Optional.ofNullable(maxresults);
        return this;
    }

    /**
     * The number of items to return. If not specified, all items will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * 
     */
    public GetWatchListRequest withMaxresults(Optional<Integer> maxresults) {
        Utils.checkNotNull(maxresults, "maxresults");
        this.maxresults = maxresults;
        return this;
    }

    /**
     * include collections in the results
     * 
     */
    public GetWatchListRequest withIncludeCollections(IncludeCollections includeCollections) {
        Utils.checkNotNull(includeCollections, "includeCollections");
        this.includeCollections = Optional.ofNullable(includeCollections);
        return this;
    }

    /**
     * include collections in the results
     * 
     */
    public GetWatchListRequest withIncludeCollections(Optional<? extends IncludeCollections> includeCollections) {
        Utils.checkNotNull(includeCollections, "includeCollections");
        this.includeCollections = includeCollections;
        return this;
    }

    /**
     * include external media in the results
     * 
     */
    public GetWatchListRequest withIncludeExternalMedia(IncludeExternalMedia includeExternalMedia) {
        Utils.checkNotNull(includeExternalMedia, "includeExternalMedia");
        this.includeExternalMedia = Optional.ofNullable(includeExternalMedia);
        return this;
    }

    /**
     * include external media in the results
     * 
     */
    public GetWatchListRequest withIncludeExternalMedia(Optional<? extends IncludeExternalMedia> includeExternalMedia) {
        Utils.checkNotNull(includeExternalMedia, "includeExternalMedia");
        this.includeExternalMedia = includeExternalMedia;
        return this;
    }

    /**
     * The index of the first item to return. If not specified, the first item will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * By default this is 0
     * 
     */
    public GetWatchListRequest withXPlexContainerStart(int xPlexContainerStart) {
        Utils.checkNotNull(xPlexContainerStart, "xPlexContainerStart");
        this.xPlexContainerStart = Optional.ofNullable(xPlexContainerStart);
        return this;
    }

    /**
     * The index of the first item to return. If not specified, the first item will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * By default this is 0
     * 
     */
    public GetWatchListRequest withXPlexContainerStart(Optional<Integer> xPlexContainerStart) {
        Utils.checkNotNull(xPlexContainerStart, "xPlexContainerStart");
        this.xPlexContainerStart = xPlexContainerStart;
        return this;
    }

    /**
     * The number of items to return. If not specified, all items will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * By default this is 50
     * 
     */
    public GetWatchListRequest withXPlexContainerSize(int xPlexContainerSize) {
        Utils.checkNotNull(xPlexContainerSize, "xPlexContainerSize");
        this.xPlexContainerSize = Optional.ofNullable(xPlexContainerSize);
        return this;
    }

    /**
     * The number of items to return. If not specified, all items will be returned.
     * If the number of items exceeds the limit, the response will be paginated.
     * By default this is 50
     * 
     */
    public GetWatchListRequest withXPlexContainerSize(Optional<Integer> xPlexContainerSize) {
        Utils.checkNotNull(xPlexContainerSize, "xPlexContainerSize");
        this.xPlexContainerSize = xPlexContainerSize;
        return this;
    }

    /**
     * An authentication token, obtained from plex.tv
     */
    public GetWatchListRequest withXPlexToken(String xPlexToken) {
        Utils.checkNotNull(xPlexToken, "xPlexToken");
        this.xPlexToken = xPlexToken;
        return this;
    }
    
    @Override
    public boolean equals(java.lang.Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        GetWatchListRequest other = (GetWatchListRequest) o;
        return 
            Objects.deepEquals(this.filter, other.filter) &&
            Objects.deepEquals(this.sort, other.sort) &&
            Objects.deepEquals(this.libtype, other.libtype) &&
            Objects.deepEquals(this.maxresults, other.maxresults) &&
            Objects.deepEquals(this.includeCollections, other.includeCollections) &&
            Objects.deepEquals(this.includeExternalMedia, other.includeExternalMedia) &&
            Objects.deepEquals(this.xPlexContainerStart, other.xPlexContainerStart) &&
            Objects.deepEquals(this.xPlexContainerSize, other.xPlexContainerSize) &&
            Objects.deepEquals(this.xPlexToken, other.xPlexToken);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(
            filter,
            sort,
            libtype,
            maxresults,
            includeCollections,
            includeExternalMedia,
            xPlexContainerStart,
            xPlexContainerSize,
            xPlexToken);
    }
    
    @Override
    public String toString() {
        return Utils.toString(GetWatchListRequest.class,
                "filter", filter,
                "sort", sort,
                "libtype", libtype,
                "maxresults", maxresults,
                "includeCollections", includeCollections,
                "includeExternalMedia", includeExternalMedia,
                "xPlexContainerStart", xPlexContainerStart,
                "xPlexContainerSize", xPlexContainerSize,
                "xPlexToken", xPlexToken);
    }
    
    public final static class Builder {
 
        private Filter filter;
 
        private Optional<String> sort = Optional.empty();
 
        private Optional<? extends Libtype> libtype = Optional.empty();
 
        private Optional<Integer> maxresults = Optional.empty();
 
        private Optional<? extends IncludeCollections> includeCollections = Optional.empty();
 
        private Optional<? extends IncludeExternalMedia> includeExternalMedia = Optional.empty();
 
        private Optional<Integer> xPlexContainerStart;
 
        private Optional<Integer> xPlexContainerSize;
 
        private String xPlexToken;  
        
        private Builder() {
          // force use of static builder() method
        }

        /**
         * Filter
         */
        public Builder filter(Filter filter) {
            Utils.checkNotNull(filter, "filter");
            this.filter = filter;
            return this;
        }

        /**
         * In the format "field:dir". Available fields are "watchlistedAt" (Added At),
         * "titleSort" (Title), "originallyAvailableAt" (Release Date), or "rating" (Critic Rating).
         * "dir" can be "asc" or "desc"
         * 
         */
        public Builder sort(String sort) {
            Utils.checkNotNull(sort, "sort");
            this.sort = Optional.ofNullable(sort);
            return this;
        }

        /**
         * In the format "field:dir". Available fields are "watchlistedAt" (Added At),
         * "titleSort" (Title), "originallyAvailableAt" (Release Date), or "rating" (Critic Rating).
         * "dir" can be "asc" or "desc"
         * 
         */
        public Builder sort(Optional<String> sort) {
            Utils.checkNotNull(sort, "sort");
            this.sort = sort;
            return this;
        }

        /**
         * The type of library to filter. Can be "movie" or "show", or all if not present.
         * 
         */
        public Builder libtype(Libtype libtype) {
            Utils.checkNotNull(libtype, "libtype");
            this.libtype = Optional.ofNullable(libtype);
            return this;
        }

        /**
         * The type of library to filter. Can be "movie" or "show", or all if not present.
         * 
         */
        public Builder libtype(Optional<? extends Libtype> libtype) {
            Utils.checkNotNull(libtype, "libtype");
            this.libtype = libtype;
            return this;
        }

        /**
         * The number of items to return. If not specified, all items will be returned.
         * If the number of items exceeds the limit, the response will be paginated.
         * 
         */
        public Builder maxresults(int maxresults) {
            Utils.checkNotNull(maxresults, "maxresults");
            this.maxresults = Optional.ofNullable(maxresults);
            return this;
        }

        /**
         * The number of items to return. If not specified, all items will be returned.
         * If the number of items exceeds the limit, the response will be paginated.
         * 
         */
        public Builder maxresults(Optional<Integer> maxresults) {
            Utils.checkNotNull(maxresults, "maxresults");
            this.maxresults = maxresults;
            return this;
        }

        /**
         * include collections in the results
         * 
         */
        public Builder includeCollections(IncludeCollections includeCollections) {
            Utils.checkNotNull(includeCollections, "includeCollections");
            this.includeCollections = Optional.ofNullable(includeCollections);
            return this;
        }

        /**
         * include collections in the results
         * 
         */
        public Builder includeCollections(Optional<? extends IncludeCollections> includeCollections) {
            Utils.checkNotNull(includeCollections, "includeCollections");
            this.includeCollections = includeCollections;
            return this;
        }

        /**
         * include external media in the results
         * 
         */
        public Builder includeExternalMedia(IncludeExternalMedia includeExternalMedia) {
            Utils.checkNotNull(includeExternalMedia, "includeExternalMedia");
            this.includeExternalMedia = Optional.ofNullable(includeExternalMedia);
            return this;
        }

        /**
         * include external media in the results
         * 
         */
        public Builder includeExternalMedia(Optional<? extends IncludeExternalMedia> includeExternalMedia) {
            Utils.checkNotNull(includeExternalMedia, "includeExternalMedia");
            this.includeExternalMedia = includeExternalMedia;
            return this;
        }

        /**
         * The index of the first item to return. If not specified, the first item will be returned.
         * If the number of items exceeds the limit, the response will be paginated.
         * By default this is 0
         * 
         */
        public Builder xPlexContainerStart(int xPlexContainerStart) {
            Utils.checkNotNull(xPlexContainerStart, "xPlexContainerStart");
            this.xPlexContainerStart = Optional.ofNullable(xPlexContainerStart);
            return this;
        }

        /**
         * The index of the first item to return. If not specified, the first item will be returned.
         * If the number of items exceeds the limit, the response will be paginated.
         * By default this is 0
         * 
         */
        public Builder xPlexContainerStart(Optional<Integer> xPlexContainerStart) {
            Utils.checkNotNull(xPlexContainerStart, "xPlexContainerStart");
            this.xPlexContainerStart = xPlexContainerStart;
            return this;
        }

        /**
         * The number of items to return. If not specified, all items will be returned.
         * If the number of items exceeds the limit, the response will be paginated.
         * By default this is 50
         * 
         */
        public Builder xPlexContainerSize(int xPlexContainerSize) {
            Utils.checkNotNull(xPlexContainerSize, "xPlexContainerSize");
            this.xPlexContainerSize = Optional.ofNullable(xPlexContainerSize);
            return this;
        }

        /**
         * The number of items to return. If not specified, all items will be returned.
         * If the number of items exceeds the limit, the response will be paginated.
         * By default this is 50
         * 
         */
        public Builder xPlexContainerSize(Optional<Integer> xPlexContainerSize) {
            Utils.checkNotNull(xPlexContainerSize, "xPlexContainerSize");
            this.xPlexContainerSize = xPlexContainerSize;
            return this;
        }

        /**
         * An authentication token, obtained from plex.tv
         */
        public Builder xPlexToken(String xPlexToken) {
            Utils.checkNotNull(xPlexToken, "xPlexToken");
            this.xPlexToken = xPlexToken;
            return this;
        }
        
        public GetWatchListRequest build() {
            if (xPlexContainerStart == null) {
                xPlexContainerStart = _SINGLETON_VALUE_XPlexContainerStart.value();
            }
            if (xPlexContainerSize == null) {
                xPlexContainerSize = _SINGLETON_VALUE_XPlexContainerSize.value();
            }            return new GetWatchListRequest(
                filter,
                sort,
                libtype,
                maxresults,
                includeCollections,
                includeExternalMedia,
                xPlexContainerStart,
                xPlexContainerSize,
                xPlexToken);
        }

        private static final LazySingletonValue<Optional<Integer>> _SINGLETON_VALUE_XPlexContainerStart =
                new LazySingletonValue<>(
                        "X-Plex-Container-Start",
                        "0",
                        new TypeReference<Optional<Integer>>() {});

        private static final LazySingletonValue<Optional<Integer>> _SINGLETON_VALUE_XPlexContainerSize =
                new LazySingletonValue<>(
                        "X-Plex-Container-Size",
                        "50",
                        new TypeReference<Optional<Integer>>() {});
    }
}

