/*
 * Jellyfin API
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 10.11.6
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

package org.openhab.binding.jellyfin.internal.gen.current.model;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.UUID;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Playback info dto.
 */
@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "OpenAPI Generator")
public class PlaybackInfoDto {
    public static final String JSON_PROPERTY_USER_ID = "UserId";
    private @org.eclipse.jdt.annotation.Nullable UUID userId;

    public static final String JSON_PROPERTY_MAX_STREAMING_BITRATE = "MaxStreamingBitrate";
    private @org.eclipse.jdt.annotation.Nullable Integer maxStreamingBitrate;

    public static final String JSON_PROPERTY_START_TIME_TICKS = "StartTimeTicks";
    private @org.eclipse.jdt.annotation.Nullable Long startTimeTicks;

    public static final String JSON_PROPERTY_AUDIO_STREAM_INDEX = "AudioStreamIndex";
    private @org.eclipse.jdt.annotation.Nullable Integer audioStreamIndex;

    public static final String JSON_PROPERTY_SUBTITLE_STREAM_INDEX = "SubtitleStreamIndex";
    private @org.eclipse.jdt.annotation.Nullable Integer subtitleStreamIndex;

    public static final String JSON_PROPERTY_MAX_AUDIO_CHANNELS = "MaxAudioChannels";
    private @org.eclipse.jdt.annotation.Nullable Integer maxAudioChannels;

    public static final String JSON_PROPERTY_MEDIA_SOURCE_ID = "MediaSourceId";
    private @org.eclipse.jdt.annotation.Nullable String mediaSourceId;

    public static final String JSON_PROPERTY_LIVE_STREAM_ID = "LiveStreamId";
    private @org.eclipse.jdt.annotation.Nullable String liveStreamId;

    public static final String JSON_PROPERTY_DEVICE_PROFILE = "DeviceProfile";
    private @org.eclipse.jdt.annotation.Nullable DeviceProfile deviceProfile;

    public static final String JSON_PROPERTY_ENABLE_DIRECT_PLAY = "EnableDirectPlay";
    private @org.eclipse.jdt.annotation.Nullable Boolean enableDirectPlay;

    public static final String JSON_PROPERTY_ENABLE_DIRECT_STREAM = "EnableDirectStream";
    private @org.eclipse.jdt.annotation.Nullable Boolean enableDirectStream;

    public static final String JSON_PROPERTY_ENABLE_TRANSCODING = "EnableTranscoding";
    private @org.eclipse.jdt.annotation.Nullable Boolean enableTranscoding;

    public static final String JSON_PROPERTY_ALLOW_VIDEO_STREAM_COPY = "AllowVideoStreamCopy";
    private @org.eclipse.jdt.annotation.Nullable Boolean allowVideoStreamCopy;

    public static final String JSON_PROPERTY_ALLOW_AUDIO_STREAM_COPY = "AllowAudioStreamCopy";
    private @org.eclipse.jdt.annotation.Nullable Boolean allowAudioStreamCopy;

    public static final String JSON_PROPERTY_AUTO_OPEN_LIVE_STREAM = "AutoOpenLiveStream";
    private @org.eclipse.jdt.annotation.Nullable Boolean autoOpenLiveStream;

    public static final String JSON_PROPERTY_ALWAYS_BURN_IN_SUBTITLE_WHEN_TRANSCODING = "AlwaysBurnInSubtitleWhenTranscoding";
    private @org.eclipse.jdt.annotation.Nullable Boolean alwaysBurnInSubtitleWhenTranscoding;

    public PlaybackInfoDto() {
    }

    public PlaybackInfoDto userId(@org.eclipse.jdt.annotation.Nullable UUID userId) {
        this.userId = userId;
        return this;
    }

    /**
     * Gets or sets the playback userId.
     * 
     * @return userId
     */
    @JsonProperty(value = JSON_PROPERTY_USER_ID)
    public @org.eclipse.jdt.annotation.Nullable UUID getUserId() {
        return userId;
    }

    @JsonProperty(value = JSON_PROPERTY_USER_ID)
    public void setUserId(@org.eclipse.jdt.annotation.Nullable UUID userId) {
        this.userId = userId;
    }

    public PlaybackInfoDto maxStreamingBitrate(@org.eclipse.jdt.annotation.Nullable Integer maxStreamingBitrate) {
        this.maxStreamingBitrate = maxStreamingBitrate;
        return this;
    }

    /**
     * Gets or sets the max streaming bitrate.
     * 
     * @return maxStreamingBitrate
     */
    @JsonProperty(value = JSON_PROPERTY_MAX_STREAMING_BITRATE)
    public @org.eclipse.jdt.annotation.Nullable Integer getMaxStreamingBitrate() {
        return maxStreamingBitrate;
    }

    @JsonProperty(value = JSON_PROPERTY_MAX_STREAMING_BITRATE)
    public void setMaxStreamingBitrate(@org.eclipse.jdt.annotation.Nullable Integer maxStreamingBitrate) {
        this.maxStreamingBitrate = maxStreamingBitrate;
    }

    public PlaybackInfoDto startTimeTicks(@org.eclipse.jdt.annotation.Nullable Long startTimeTicks) {
        this.startTimeTicks = startTimeTicks;
        return this;
    }

    /**
     * Gets or sets the start time in ticks.
     * 
     * @return startTimeTicks
     */
    @JsonProperty(value = JSON_PROPERTY_START_TIME_TICKS)
    public @org.eclipse.jdt.annotation.Nullable Long getStartTimeTicks() {
        return startTimeTicks;
    }

    @JsonProperty(value = JSON_PROPERTY_START_TIME_TICKS)
    public void setStartTimeTicks(@org.eclipse.jdt.annotation.Nullable Long startTimeTicks) {
        this.startTimeTicks = startTimeTicks;
    }

    public PlaybackInfoDto audioStreamIndex(@org.eclipse.jdt.annotation.Nullable Integer audioStreamIndex) {
        this.audioStreamIndex = audioStreamIndex;
        return this;
    }

    /**
     * Gets or sets the audio stream index.
     * 
     * @return audioStreamIndex
     */
    @JsonProperty(value = JSON_PROPERTY_AUDIO_STREAM_INDEX)
    public @org.eclipse.jdt.annotation.Nullable Integer getAudioStreamIndex() {
        return audioStreamIndex;
    }

    @JsonProperty(value = JSON_PROPERTY_AUDIO_STREAM_INDEX)
    public void setAudioStreamIndex(@org.eclipse.jdt.annotation.Nullable Integer audioStreamIndex) {
        this.audioStreamIndex = audioStreamIndex;
    }

    public PlaybackInfoDto subtitleStreamIndex(@org.eclipse.jdt.annotation.Nullable Integer subtitleStreamIndex) {
        this.subtitleStreamIndex = subtitleStreamIndex;
        return this;
    }

    /**
     * Gets or sets the subtitle stream index.
     * 
     * @return subtitleStreamIndex
     */
    @JsonProperty(value = JSON_PROPERTY_SUBTITLE_STREAM_INDEX)
    public @org.eclipse.jdt.annotation.Nullable Integer getSubtitleStreamIndex() {
        return subtitleStreamIndex;
    }

    @JsonProperty(value = JSON_PROPERTY_SUBTITLE_STREAM_INDEX)
    public void setSubtitleStreamIndex(@org.eclipse.jdt.annotation.Nullable Integer subtitleStreamIndex) {
        this.subtitleStreamIndex = subtitleStreamIndex;
    }

    public PlaybackInfoDto maxAudioChannels(@org.eclipse.jdt.annotation.Nullable Integer maxAudioChannels) {
        this.maxAudioChannels = maxAudioChannels;
        return this;
    }

    /**
     * Gets or sets the max audio channels.
     * 
     * @return maxAudioChannels
     */
    @JsonProperty(value = JSON_PROPERTY_MAX_AUDIO_CHANNELS)
    public @org.eclipse.jdt.annotation.Nullable Integer getMaxAudioChannels() {
        return maxAudioChannels;
    }

    @JsonProperty(value = JSON_PROPERTY_MAX_AUDIO_CHANNELS)
    public void setMaxAudioChannels(@org.eclipse.jdt.annotation.Nullable Integer maxAudioChannels) {
        this.maxAudioChannels = maxAudioChannels;
    }

    public PlaybackInfoDto mediaSourceId(@org.eclipse.jdt.annotation.Nullable String mediaSourceId) {
        this.mediaSourceId = mediaSourceId;
        return this;
    }

    /**
     * Gets or sets the media source id.
     * 
     * @return mediaSourceId
     */
    @JsonProperty(value = JSON_PROPERTY_MEDIA_SOURCE_ID)
    public @org.eclipse.jdt.annotation.Nullable String getMediaSourceId() {
        return mediaSourceId;
    }

    @JsonProperty(value = JSON_PROPERTY_MEDIA_SOURCE_ID)
    public void setMediaSourceId(@org.eclipse.jdt.annotation.Nullable String mediaSourceId) {
        this.mediaSourceId = mediaSourceId;
    }

    public PlaybackInfoDto liveStreamId(@org.eclipse.jdt.annotation.Nullable String liveStreamId) {
        this.liveStreamId = liveStreamId;
        return this;
    }

    /**
     * Gets or sets the live stream id.
     * 
     * @return liveStreamId
     */
    @JsonProperty(value = JSON_PROPERTY_LIVE_STREAM_ID)
    public @org.eclipse.jdt.annotation.Nullable String getLiveStreamId() {
        return liveStreamId;
    }

    @JsonProperty(value = JSON_PROPERTY_LIVE_STREAM_ID)
    public void setLiveStreamId(@org.eclipse.jdt.annotation.Nullable String liveStreamId) {
        this.liveStreamId = liveStreamId;
    }

    public PlaybackInfoDto deviceProfile(@org.eclipse.jdt.annotation.Nullable DeviceProfile deviceProfile) {
        this.deviceProfile = deviceProfile;
        return this;
    }

    /**
     * A MediaBrowser.Model.Dlna.DeviceProfile represents a set of metadata which determines which content a certain
     * device is able to play. &lt;br /&gt; Specifically, it defines the supported &lt;see
     * cref&#x3D;\&quot;P:MediaBrowser.Model.Dlna.DeviceProfile.ContainerProfiles\&quot;&gt;containers&lt;/see&gt; and
     * &lt;see cref&#x3D;\&quot;P:MediaBrowser.Model.Dlna.DeviceProfile.CodecProfiles\&quot;&gt;codecs&lt;/see&gt;
     * (video and/or audio, including codec profiles and levels) the device is able to direct play (without transcoding
     * or remuxing), as well as which &lt;see
     * cref&#x3D;\&quot;P:MediaBrowser.Model.Dlna.DeviceProfile.TranscodingProfiles\&quot;&gt;containers/codecs to
     * transcode to&lt;/see&gt; in case it isn&#39;t.
     * 
     * @return deviceProfile
     */
    @JsonProperty(value = JSON_PROPERTY_DEVICE_PROFILE)
    public @org.eclipse.jdt.annotation.Nullable DeviceProfile getDeviceProfile() {
        return deviceProfile;
    }

    @JsonProperty(value = JSON_PROPERTY_DEVICE_PROFILE)
    public void setDeviceProfile(@org.eclipse.jdt.annotation.Nullable DeviceProfile deviceProfile) {
        this.deviceProfile = deviceProfile;
    }

    public PlaybackInfoDto enableDirectPlay(@org.eclipse.jdt.annotation.Nullable Boolean enableDirectPlay) {
        this.enableDirectPlay = enableDirectPlay;
        return this;
    }

    /**
     * Gets or sets a value indicating whether to enable direct play.
     * 
     * @return enableDirectPlay
     */
    @JsonProperty(value = JSON_PROPERTY_ENABLE_DIRECT_PLAY)
    public @org.eclipse.jdt.annotation.Nullable Boolean getEnableDirectPlay() {
        return enableDirectPlay;
    }

    @JsonProperty(value = JSON_PROPERTY_ENABLE_DIRECT_PLAY)
    public void setEnableDirectPlay(@org.eclipse.jdt.annotation.Nullable Boolean enableDirectPlay) {
        this.enableDirectPlay = enableDirectPlay;
    }

    public PlaybackInfoDto enableDirectStream(@org.eclipse.jdt.annotation.Nullable Boolean enableDirectStream) {
        this.enableDirectStream = enableDirectStream;
        return this;
    }

    /**
     * Gets or sets a value indicating whether to enable direct stream.
     * 
     * @return enableDirectStream
     */
    @JsonProperty(value = JSON_PROPERTY_ENABLE_DIRECT_STREAM)
    public @org.eclipse.jdt.annotation.Nullable Boolean getEnableDirectStream() {
        return enableDirectStream;
    }

    @JsonProperty(value = JSON_PROPERTY_ENABLE_DIRECT_STREAM)
    public void setEnableDirectStream(@org.eclipse.jdt.annotation.Nullable Boolean enableDirectStream) {
        this.enableDirectStream = enableDirectStream;
    }

    public PlaybackInfoDto enableTranscoding(@org.eclipse.jdt.annotation.Nullable Boolean enableTranscoding) {
        this.enableTranscoding = enableTranscoding;
        return this;
    }

    /**
     * Gets or sets a value indicating whether to enable transcoding.
     * 
     * @return enableTranscoding
     */
    @JsonProperty(value = JSON_PROPERTY_ENABLE_TRANSCODING)
    public @org.eclipse.jdt.annotation.Nullable Boolean getEnableTranscoding() {
        return enableTranscoding;
    }

    @JsonProperty(value = JSON_PROPERTY_ENABLE_TRANSCODING)
    public void setEnableTranscoding(@org.eclipse.jdt.annotation.Nullable Boolean enableTranscoding) {
        this.enableTranscoding = enableTranscoding;
    }

    public PlaybackInfoDto allowVideoStreamCopy(@org.eclipse.jdt.annotation.Nullable Boolean allowVideoStreamCopy) {
        this.allowVideoStreamCopy = allowVideoStreamCopy;
        return this;
    }

    /**
     * Gets or sets a value indicating whether to enable video stream copy.
     * 
     * @return allowVideoStreamCopy
     */
    @JsonProperty(value = JSON_PROPERTY_ALLOW_VIDEO_STREAM_COPY)
    public @org.eclipse.jdt.annotation.Nullable Boolean getAllowVideoStreamCopy() {
        return allowVideoStreamCopy;
    }

    @JsonProperty(value = JSON_PROPERTY_ALLOW_VIDEO_STREAM_COPY)
    public void setAllowVideoStreamCopy(@org.eclipse.jdt.annotation.Nullable Boolean allowVideoStreamCopy) {
        this.allowVideoStreamCopy = allowVideoStreamCopy;
    }

    public PlaybackInfoDto allowAudioStreamCopy(@org.eclipse.jdt.annotation.Nullable Boolean allowAudioStreamCopy) {
        this.allowAudioStreamCopy = allowAudioStreamCopy;
        return this;
    }

    /**
     * Gets or sets a value indicating whether to allow audio stream copy.
     * 
     * @return allowAudioStreamCopy
     */
    @JsonProperty(value = JSON_PROPERTY_ALLOW_AUDIO_STREAM_COPY)
    public @org.eclipse.jdt.annotation.Nullable Boolean getAllowAudioStreamCopy() {
        return allowAudioStreamCopy;
    }

    @JsonProperty(value = JSON_PROPERTY_ALLOW_AUDIO_STREAM_COPY)
    public void setAllowAudioStreamCopy(@org.eclipse.jdt.annotation.Nullable Boolean allowAudioStreamCopy) {
        this.allowAudioStreamCopy = allowAudioStreamCopy;
    }

    public PlaybackInfoDto autoOpenLiveStream(@org.eclipse.jdt.annotation.Nullable Boolean autoOpenLiveStream) {
        this.autoOpenLiveStream = autoOpenLiveStream;
        return this;
    }

    /**
     * Gets or sets a value indicating whether to auto open the live stream.
     * 
     * @return autoOpenLiveStream
     */
    @JsonProperty(value = JSON_PROPERTY_AUTO_OPEN_LIVE_STREAM)
    public @org.eclipse.jdt.annotation.Nullable Boolean getAutoOpenLiveStream() {
        return autoOpenLiveStream;
    }

    @JsonProperty(value = JSON_PROPERTY_AUTO_OPEN_LIVE_STREAM)
    public void setAutoOpenLiveStream(@org.eclipse.jdt.annotation.Nullable Boolean autoOpenLiveStream) {
        this.autoOpenLiveStream = autoOpenLiveStream;
    }

    public PlaybackInfoDto alwaysBurnInSubtitleWhenTranscoding(
            @org.eclipse.jdt.annotation.Nullable Boolean alwaysBurnInSubtitleWhenTranscoding) {
        this.alwaysBurnInSubtitleWhenTranscoding = alwaysBurnInSubtitleWhenTranscoding;
        return this;
    }

    /**
     * Gets or sets a value indicating whether always burn in subtitles when transcoding.
     * 
     * @return alwaysBurnInSubtitleWhenTranscoding
     */
    @JsonProperty(value = JSON_PROPERTY_ALWAYS_BURN_IN_SUBTITLE_WHEN_TRANSCODING)
    public @org.eclipse.jdt.annotation.Nullable Boolean getAlwaysBurnInSubtitleWhenTranscoding() {
        return alwaysBurnInSubtitleWhenTranscoding;
    }

    @JsonProperty(value = JSON_PROPERTY_ALWAYS_BURN_IN_SUBTITLE_WHEN_TRANSCODING)
    public void setAlwaysBurnInSubtitleWhenTranscoding(
            @org.eclipse.jdt.annotation.Nullable Boolean alwaysBurnInSubtitleWhenTranscoding) {
        this.alwaysBurnInSubtitleWhenTranscoding = alwaysBurnInSubtitleWhenTranscoding;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        PlaybackInfoDto playbackInfoDto = (PlaybackInfoDto) o;
        return Objects.equals(this.userId, playbackInfoDto.userId)
                && Objects.equals(this.maxStreamingBitrate, playbackInfoDto.maxStreamingBitrate)
                && Objects.equals(this.startTimeTicks, playbackInfoDto.startTimeTicks)
                && Objects.equals(this.audioStreamIndex, playbackInfoDto.audioStreamIndex)
                && Objects.equals(this.subtitleStreamIndex, playbackInfoDto.subtitleStreamIndex)
                && Objects.equals(this.maxAudioChannels, playbackInfoDto.maxAudioChannels)
                && Objects.equals(this.mediaSourceId, playbackInfoDto.mediaSourceId)
                && Objects.equals(this.liveStreamId, playbackInfoDto.liveStreamId)
                && Objects.equals(this.deviceProfile, playbackInfoDto.deviceProfile)
                && Objects.equals(this.enableDirectPlay, playbackInfoDto.enableDirectPlay)
                && Objects.equals(this.enableDirectStream, playbackInfoDto.enableDirectStream)
                && Objects.equals(this.enableTranscoding, playbackInfoDto.enableTranscoding)
                && Objects.equals(this.allowVideoStreamCopy, playbackInfoDto.allowVideoStreamCopy)
                && Objects.equals(this.allowAudioStreamCopy, playbackInfoDto.allowAudioStreamCopy)
                && Objects.equals(this.autoOpenLiveStream, playbackInfoDto.autoOpenLiveStream) && Objects.equals(
                        this.alwaysBurnInSubtitleWhenTranscoding, playbackInfoDto.alwaysBurnInSubtitleWhenTranscoding);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userId, maxStreamingBitrate, startTimeTicks, audioStreamIndex, subtitleStreamIndex,
                maxAudioChannels, mediaSourceId, liveStreamId, deviceProfile, enableDirectPlay, enableDirectStream,
                enableTranscoding, allowVideoStreamCopy, allowAudioStreamCopy, autoOpenLiveStream,
                alwaysBurnInSubtitleWhenTranscoding);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("class PlaybackInfoDto {\n");
        sb.append("    userId: ").append(toIndentedString(userId)).append("\n");
        sb.append("    maxStreamingBitrate: ").append(toIndentedString(maxStreamingBitrate)).append("\n");
        sb.append("    startTimeTicks: ").append(toIndentedString(startTimeTicks)).append("\n");
        sb.append("    audioStreamIndex: ").append(toIndentedString(audioStreamIndex)).append("\n");
        sb.append("    subtitleStreamIndex: ").append(toIndentedString(subtitleStreamIndex)).append("\n");
        sb.append("    maxAudioChannels: ").append(toIndentedString(maxAudioChannels)).append("\n");
        sb.append("    mediaSourceId: ").append(toIndentedString(mediaSourceId)).append("\n");
        sb.append("    liveStreamId: ").append(toIndentedString(liveStreamId)).append("\n");
        sb.append("    deviceProfile: ").append(toIndentedString(deviceProfile)).append("\n");
        sb.append("    enableDirectPlay: ").append(toIndentedString(enableDirectPlay)).append("\n");
        sb.append("    enableDirectStream: ").append(toIndentedString(enableDirectStream)).append("\n");
        sb.append("    enableTranscoding: ").append(toIndentedString(enableTranscoding)).append("\n");
        sb.append("    allowVideoStreamCopy: ").append(toIndentedString(allowVideoStreamCopy)).append("\n");
        sb.append("    allowAudioStreamCopy: ").append(toIndentedString(allowAudioStreamCopy)).append("\n");
        sb.append("    autoOpenLiveStream: ").append(toIndentedString(autoOpenLiveStream)).append("\n");
        sb.append("    alwaysBurnInSubtitleWhenTranscoding: ")
                .append(toIndentedString(alwaysBurnInSubtitleWhenTranscoding)).append("\n");
        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) {
        return o == null ? "null" : o.toString().replace("\n", "\n    ");
    }

    /**
     * Convert the instance into URL query string.
     *
     * @return URL query string
     */
    public String toUrlQueryString() {
        return toUrlQueryString(null);
    }

    /**
     * Convert the instance into URL query string.
     *
     * @param prefix prefix of the query string
     * @return URL query string
     */
    public String toUrlQueryString(String prefix) {
        String suffix = "";
        String containerSuffix = "";
        String containerPrefix = "";
        if (prefix == null) {
            // style=form, explode=true, e.g. /pet?name=cat&type=manx
            prefix = "";
        } else {
            // deepObject style e.g. /pet?id[name]=cat&id[type]=manx
            prefix = prefix + "[";
            suffix = "]";
            containerSuffix = "]";
            containerPrefix = "[";
        }

        StringJoiner joiner = new StringJoiner("&");

        // add `UserId` to the URL query string
        if (getUserId() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sUserId%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getUserId()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `MaxStreamingBitrate` to the URL query string
        if (getMaxStreamingBitrate() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sMaxStreamingBitrate%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getMaxStreamingBitrate()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `StartTimeTicks` to the URL query string
        if (getStartTimeTicks() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sStartTimeTicks%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getStartTimeTicks()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `AudioStreamIndex` to the URL query string
        if (getAudioStreamIndex() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sAudioStreamIndex%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getAudioStreamIndex()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `SubtitleStreamIndex` to the URL query string
        if (getSubtitleStreamIndex() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sSubtitleStreamIndex%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getSubtitleStreamIndex()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `MaxAudioChannels` to the URL query string
        if (getMaxAudioChannels() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sMaxAudioChannels%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getMaxAudioChannels()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `MediaSourceId` to the URL query string
        if (getMediaSourceId() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sMediaSourceId%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getMediaSourceId()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `LiveStreamId` to the URL query string
        if (getLiveStreamId() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sLiveStreamId%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getLiveStreamId()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `DeviceProfile` to the URL query string
        if (getDeviceProfile() != null) {
            joiner.add(getDeviceProfile().toUrlQueryString(prefix + "DeviceProfile" + suffix));
        }

        // add `EnableDirectPlay` to the URL query string
        if (getEnableDirectPlay() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sEnableDirectPlay%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getEnableDirectPlay()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `EnableDirectStream` to the URL query string
        if (getEnableDirectStream() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sEnableDirectStream%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getEnableDirectStream()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `EnableTranscoding` to the URL query string
        if (getEnableTranscoding() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sEnableTranscoding%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getEnableTranscoding()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `AllowVideoStreamCopy` to the URL query string
        if (getAllowVideoStreamCopy() != null) {
            try {
                joiner.add(
                        String.format(java.util.Locale.ROOT, "%sAllowVideoStreamCopy%s=%s", prefix, suffix, URLEncoder
                                .encode(String.valueOf(getAllowVideoStreamCopy()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `AllowAudioStreamCopy` to the URL query string
        if (getAllowAudioStreamCopy() != null) {
            try {
                joiner.add(
                        String.format(java.util.Locale.ROOT, "%sAllowAudioStreamCopy%s=%s", prefix, suffix, URLEncoder
                                .encode(String.valueOf(getAllowAudioStreamCopy()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `AutoOpenLiveStream` to the URL query string
        if (getAutoOpenLiveStream() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sAutoOpenLiveStream%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getAutoOpenLiveStream()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        // add `AlwaysBurnInSubtitleWhenTranscoding` to the URL query string
        if (getAlwaysBurnInSubtitleWhenTranscoding() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sAlwaysBurnInSubtitleWhenTranscoding%s=%s", prefix,
                        suffix, URLEncoder.encode(String.valueOf(getAlwaysBurnInSubtitleWhenTranscoding()), "UTF-8")
                                .replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

        return joiner.toString();
    }

    public static class Builder {

        private PlaybackInfoDto instance;

        public Builder() {
            this(new PlaybackInfoDto());
        }

        protected Builder(PlaybackInfoDto instance) {
            this.instance = instance;
        }

        public PlaybackInfoDto.Builder userId(UUID userId) {
            this.instance.userId = userId;
            return this;
        }

        public PlaybackInfoDto.Builder maxStreamingBitrate(Integer maxStreamingBitrate) {
            this.instance.maxStreamingBitrate = maxStreamingBitrate;
            return this;
        }

        public PlaybackInfoDto.Builder startTimeTicks(Long startTimeTicks) {
            this.instance.startTimeTicks = startTimeTicks;
            return this;
        }

        public PlaybackInfoDto.Builder audioStreamIndex(Integer audioStreamIndex) {
            this.instance.audioStreamIndex = audioStreamIndex;
            return this;
        }

        public PlaybackInfoDto.Builder subtitleStreamIndex(Integer subtitleStreamIndex) {
            this.instance.subtitleStreamIndex = subtitleStreamIndex;
            return this;
        }

        public PlaybackInfoDto.Builder maxAudioChannels(Integer maxAudioChannels) {
            this.instance.maxAudioChannels = maxAudioChannels;
            return this;
        }

        public PlaybackInfoDto.Builder mediaSourceId(String mediaSourceId) {
            this.instance.mediaSourceId = mediaSourceId;
            return this;
        }

        public PlaybackInfoDto.Builder liveStreamId(String liveStreamId) {
            this.instance.liveStreamId = liveStreamId;
            return this;
        }

        public PlaybackInfoDto.Builder deviceProfile(DeviceProfile deviceProfile) {
            this.instance.deviceProfile = deviceProfile;
            return this;
        }

        public PlaybackInfoDto.Builder enableDirectPlay(Boolean enableDirectPlay) {
            this.instance.enableDirectPlay = enableDirectPlay;
            return this;
        }

        public PlaybackInfoDto.Builder enableDirectStream(Boolean enableDirectStream) {
            this.instance.enableDirectStream = enableDirectStream;
            return this;
        }

        public PlaybackInfoDto.Builder enableTranscoding(Boolean enableTranscoding) {
            this.instance.enableTranscoding = enableTranscoding;
            return this;
        }

        public PlaybackInfoDto.Builder allowVideoStreamCopy(Boolean allowVideoStreamCopy) {
            this.instance.allowVideoStreamCopy = allowVideoStreamCopy;
            return this;
        }

        public PlaybackInfoDto.Builder allowAudioStreamCopy(Boolean allowAudioStreamCopy) {
            this.instance.allowAudioStreamCopy = allowAudioStreamCopy;
            return this;
        }

        public PlaybackInfoDto.Builder autoOpenLiveStream(Boolean autoOpenLiveStream) {
            this.instance.autoOpenLiveStream = autoOpenLiveStream;
            return this;
        }

        public PlaybackInfoDto.Builder alwaysBurnInSubtitleWhenTranscoding(
                Boolean alwaysBurnInSubtitleWhenTranscoding) {
            this.instance.alwaysBurnInSubtitleWhenTranscoding = alwaysBurnInSubtitleWhenTranscoding;
            return this;
        }

        /**
         * returns a built PlaybackInfoDto instance.
         *
         * The builder is not reusable.
         */
        public PlaybackInfoDto build() {
            try {
                return this.instance;
            } finally {
                // ensure that this.instance is not reused
                this.instance = null;
            }
        }

        @Override
        public String toString() {
            return getClass() + "=(" + instance + ")";
        }
    }

    /**
     * Create a builder with no initialized field.
     */
    public static PlaybackInfoDto.Builder builder() {
        return new PlaybackInfoDto.Builder();
    }

    /**
     * Create a builder with a shallow copy of this instance.
     */
    public PlaybackInfoDto.Builder toBuilder() {
        return new PlaybackInfoDto.Builder().userId(getUserId()).maxStreamingBitrate(getMaxStreamingBitrate())
                .startTimeTicks(getStartTimeTicks()).audioStreamIndex(getAudioStreamIndex())
                .subtitleStreamIndex(getSubtitleStreamIndex()).maxAudioChannels(getMaxAudioChannels())
                .mediaSourceId(getMediaSourceId()).liveStreamId(getLiveStreamId()).deviceProfile(getDeviceProfile())
                .enableDirectPlay(getEnableDirectPlay()).enableDirectStream(getEnableDirectStream())
                .enableTranscoding(getEnableTranscoding()).allowVideoStreamCopy(getAllowVideoStreamCopy())
                .allowAudioStreamCopy(getAllowAudioStreamCopy()).autoOpenLiveStream(getAutoOpenLiveStream())
                .alwaysBurnInSubtitleWhenTranscoding(getAlwaysBurnInSubtitleWhenTranscoding());
    }
}
