/*
 * 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.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Class holding information on a running transcode.
 */
@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "OpenAPI Generator")
public class TranscodingInfo {
    public static final String JSON_PROPERTY_AUDIO_CODEC = "AudioCodec";
    private @org.eclipse.jdt.annotation.Nullable String audioCodec;

    public static final String JSON_PROPERTY_VIDEO_CODEC = "VideoCodec";
    private @org.eclipse.jdt.annotation.Nullable String videoCodec;

    public static final String JSON_PROPERTY_CONTAINER = "Container";
    private @org.eclipse.jdt.annotation.Nullable String container;

    public static final String JSON_PROPERTY_IS_VIDEO_DIRECT = "IsVideoDirect";
    private @org.eclipse.jdt.annotation.Nullable Boolean isVideoDirect;

    public static final String JSON_PROPERTY_IS_AUDIO_DIRECT = "IsAudioDirect";
    private @org.eclipse.jdt.annotation.Nullable Boolean isAudioDirect;

    public static final String JSON_PROPERTY_BITRATE = "Bitrate";
    private @org.eclipse.jdt.annotation.Nullable Integer bitrate;

    public static final String JSON_PROPERTY_FRAMERATE = "Framerate";
    private @org.eclipse.jdt.annotation.Nullable Float framerate;

    public static final String JSON_PROPERTY_COMPLETION_PERCENTAGE = "CompletionPercentage";
    private @org.eclipse.jdt.annotation.Nullable Double completionPercentage;

    public static final String JSON_PROPERTY_WIDTH = "Width";
    private @org.eclipse.jdt.annotation.Nullable Integer width;

    public static final String JSON_PROPERTY_HEIGHT = "Height";
    private @org.eclipse.jdt.annotation.Nullable Integer height;

    public static final String JSON_PROPERTY_AUDIO_CHANNELS = "AudioChannels";
    private @org.eclipse.jdt.annotation.Nullable Integer audioChannels;

    public static final String JSON_PROPERTY_HARDWARE_ACCELERATION_TYPE = "HardwareAccelerationType";
    private @org.eclipse.jdt.annotation.Nullable HardwareAccelerationType hardwareAccelerationType;

    public static final String JSON_PROPERTY_TRANSCODE_REASONS = "TranscodeReasons";
    private @org.eclipse.jdt.annotation.Nullable List<TranscodeReason> transcodeReasons = new ArrayList<>();

    public TranscodingInfo() {
    }

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

    /**
     * Gets or sets the thread count used for encoding.
     * 
     * @return audioCodec
     */
    @JsonProperty(value = JSON_PROPERTY_AUDIO_CODEC)
    public @org.eclipse.jdt.annotation.Nullable String getAudioCodec() {
        return audioCodec;
    }

    @JsonProperty(value = JSON_PROPERTY_AUDIO_CODEC)
    public void setAudioCodec(@org.eclipse.jdt.annotation.Nullable String audioCodec) {
        this.audioCodec = audioCodec;
    }

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

    /**
     * Gets or sets the thread count used for encoding.
     * 
     * @return videoCodec
     */
    @JsonProperty(value = JSON_PROPERTY_VIDEO_CODEC)
    public @org.eclipse.jdt.annotation.Nullable String getVideoCodec() {
        return videoCodec;
    }

    @JsonProperty(value = JSON_PROPERTY_VIDEO_CODEC)
    public void setVideoCodec(@org.eclipse.jdt.annotation.Nullable String videoCodec) {
        this.videoCodec = videoCodec;
    }

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

    /**
     * Gets or sets the thread count used for encoding.
     * 
     * @return container
     */
    @JsonProperty(value = JSON_PROPERTY_CONTAINER)
    public @org.eclipse.jdt.annotation.Nullable String getContainer() {
        return container;
    }

    @JsonProperty(value = JSON_PROPERTY_CONTAINER)
    public void setContainer(@org.eclipse.jdt.annotation.Nullable String container) {
        this.container = container;
    }

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

    /**
     * Gets or sets a value indicating whether the video is passed through.
     * 
     * @return isVideoDirect
     */
    @JsonProperty(value = JSON_PROPERTY_IS_VIDEO_DIRECT)
    public @org.eclipse.jdt.annotation.Nullable Boolean getIsVideoDirect() {
        return isVideoDirect;
    }

    @JsonProperty(value = JSON_PROPERTY_IS_VIDEO_DIRECT)
    public void setIsVideoDirect(@org.eclipse.jdt.annotation.Nullable Boolean isVideoDirect) {
        this.isVideoDirect = isVideoDirect;
    }

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

    /**
     * Gets or sets a value indicating whether the audio is passed through.
     * 
     * @return isAudioDirect
     */
    @JsonProperty(value = JSON_PROPERTY_IS_AUDIO_DIRECT)
    public @org.eclipse.jdt.annotation.Nullable Boolean getIsAudioDirect() {
        return isAudioDirect;
    }

    @JsonProperty(value = JSON_PROPERTY_IS_AUDIO_DIRECT)
    public void setIsAudioDirect(@org.eclipse.jdt.annotation.Nullable Boolean isAudioDirect) {
        this.isAudioDirect = isAudioDirect;
    }

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

    /**
     * Gets or sets the bitrate.
     * 
     * @return bitrate
     */
    @JsonProperty(value = JSON_PROPERTY_BITRATE)
    public @org.eclipse.jdt.annotation.Nullable Integer getBitrate() {
        return bitrate;
    }

    @JsonProperty(value = JSON_PROPERTY_BITRATE)
    public void setBitrate(@org.eclipse.jdt.annotation.Nullable Integer bitrate) {
        this.bitrate = bitrate;
    }

    public TranscodingInfo framerate(@org.eclipse.jdt.annotation.Nullable Float framerate) {
        this.framerate = framerate;
        return this;
    }

    /**
     * Gets or sets the framerate.
     * 
     * @return framerate
     */
    @JsonProperty(value = JSON_PROPERTY_FRAMERATE)
    public @org.eclipse.jdt.annotation.Nullable Float getFramerate() {
        return framerate;
    }

    @JsonProperty(value = JSON_PROPERTY_FRAMERATE)
    public void setFramerate(@org.eclipse.jdt.annotation.Nullable Float framerate) {
        this.framerate = framerate;
    }

    public TranscodingInfo completionPercentage(@org.eclipse.jdt.annotation.Nullable Double completionPercentage) {
        this.completionPercentage = completionPercentage;
        return this;
    }

    /**
     * Gets or sets the completion percentage.
     * 
     * @return completionPercentage
     */
    @JsonProperty(value = JSON_PROPERTY_COMPLETION_PERCENTAGE)
    public @org.eclipse.jdt.annotation.Nullable Double getCompletionPercentage() {
        return completionPercentage;
    }

    @JsonProperty(value = JSON_PROPERTY_COMPLETION_PERCENTAGE)
    public void setCompletionPercentage(@org.eclipse.jdt.annotation.Nullable Double completionPercentage) {
        this.completionPercentage = completionPercentage;
    }

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

    /**
     * Gets or sets the video width.
     * 
     * @return width
     */
    @JsonProperty(value = JSON_PROPERTY_WIDTH)
    public @org.eclipse.jdt.annotation.Nullable Integer getWidth() {
        return width;
    }

    @JsonProperty(value = JSON_PROPERTY_WIDTH)
    public void setWidth(@org.eclipse.jdt.annotation.Nullable Integer width) {
        this.width = width;
    }

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

    /**
     * Gets or sets the video height.
     * 
     * @return height
     */
    @JsonProperty(value = JSON_PROPERTY_HEIGHT)
    public @org.eclipse.jdt.annotation.Nullable Integer getHeight() {
        return height;
    }

    @JsonProperty(value = JSON_PROPERTY_HEIGHT)
    public void setHeight(@org.eclipse.jdt.annotation.Nullable Integer height) {
        this.height = height;
    }

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

    /**
     * Gets or sets the audio channels.
     * 
     * @return audioChannels
     */
    @JsonProperty(value = JSON_PROPERTY_AUDIO_CHANNELS)
    public @org.eclipse.jdt.annotation.Nullable Integer getAudioChannels() {
        return audioChannels;
    }

    @JsonProperty(value = JSON_PROPERTY_AUDIO_CHANNELS)
    public void setAudioChannels(@org.eclipse.jdt.annotation.Nullable Integer audioChannels) {
        this.audioChannels = audioChannels;
    }

    public TranscodingInfo hardwareAccelerationType(
            @org.eclipse.jdt.annotation.Nullable HardwareAccelerationType hardwareAccelerationType) {
        this.hardwareAccelerationType = hardwareAccelerationType;
        return this;
    }

    /**
     * Gets or sets the hardware acceleration type.
     * 
     * @return hardwareAccelerationType
     */
    @JsonProperty(value = JSON_PROPERTY_HARDWARE_ACCELERATION_TYPE)
    public @org.eclipse.jdt.annotation.Nullable HardwareAccelerationType getHardwareAccelerationType() {
        return hardwareAccelerationType;
    }

    @JsonProperty(value = JSON_PROPERTY_HARDWARE_ACCELERATION_TYPE)
    public void setHardwareAccelerationType(
            @org.eclipse.jdt.annotation.Nullable HardwareAccelerationType hardwareAccelerationType) {
        this.hardwareAccelerationType = hardwareAccelerationType;
    }

    public TranscodingInfo transcodeReasons(
            @org.eclipse.jdt.annotation.Nullable List<TranscodeReason> transcodeReasons) {
        this.transcodeReasons = transcodeReasons;
        return this;
    }

    public TranscodingInfo addTranscodeReasonsItem(TranscodeReason transcodeReasonsItem) {
        if (this.transcodeReasons == null) {
            this.transcodeReasons = new ArrayList<>();
        }
        this.transcodeReasons.add(transcodeReasonsItem);
        return this;
    }

    /**
     * Gets or sets the transcode reasons.
     * 
     * @return transcodeReasons
     */
    @JsonProperty(value = JSON_PROPERTY_TRANSCODE_REASONS)
    public @org.eclipse.jdt.annotation.Nullable List<TranscodeReason> getTranscodeReasons() {
        return transcodeReasons;
    }

    @JsonProperty(value = JSON_PROPERTY_TRANSCODE_REASONS)
    public void setTranscodeReasons(@org.eclipse.jdt.annotation.Nullable List<TranscodeReason> transcodeReasons) {
        this.transcodeReasons = transcodeReasons;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        TranscodingInfo transcodingInfo = (TranscodingInfo) o;
        return Objects.equals(this.audioCodec, transcodingInfo.audioCodec)
                && Objects.equals(this.videoCodec, transcodingInfo.videoCodec)
                && Objects.equals(this.container, transcodingInfo.container)
                && Objects.equals(this.isVideoDirect, transcodingInfo.isVideoDirect)
                && Objects.equals(this.isAudioDirect, transcodingInfo.isAudioDirect)
                && Objects.equals(this.bitrate, transcodingInfo.bitrate)
                && Objects.equals(this.framerate, transcodingInfo.framerate)
                && Objects.equals(this.completionPercentage, transcodingInfo.completionPercentage)
                && Objects.equals(this.width, transcodingInfo.width)
                && Objects.equals(this.height, transcodingInfo.height)
                && Objects.equals(this.audioChannels, transcodingInfo.audioChannels)
                && Objects.equals(this.hardwareAccelerationType, transcodingInfo.hardwareAccelerationType)
                && Objects.equals(this.transcodeReasons, transcodingInfo.transcodeReasons);
    }

    @Override
    public int hashCode() {
        return Objects.hash(audioCodec, videoCodec, container, isVideoDirect, isAudioDirect, bitrate, framerate,
                completionPercentage, width, height, audioChannels, hardwareAccelerationType, transcodeReasons);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("class TranscodingInfo {\n");
        sb.append("    audioCodec: ").append(toIndentedString(audioCodec)).append("\n");
        sb.append("    videoCodec: ").append(toIndentedString(videoCodec)).append("\n");
        sb.append("    container: ").append(toIndentedString(container)).append("\n");
        sb.append("    isVideoDirect: ").append(toIndentedString(isVideoDirect)).append("\n");
        sb.append("    isAudioDirect: ").append(toIndentedString(isAudioDirect)).append("\n");
        sb.append("    bitrate: ").append(toIndentedString(bitrate)).append("\n");
        sb.append("    framerate: ").append(toIndentedString(framerate)).append("\n");
        sb.append("    completionPercentage: ").append(toIndentedString(completionPercentage)).append("\n");
        sb.append("    width: ").append(toIndentedString(width)).append("\n");
        sb.append("    height: ").append(toIndentedString(height)).append("\n");
        sb.append("    audioChannels: ").append(toIndentedString(audioChannels)).append("\n");
        sb.append("    hardwareAccelerationType: ").append(toIndentedString(hardwareAccelerationType)).append("\n");
        sb.append("    transcodeReasons: ").append(toIndentedString(transcodeReasons)).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 `AudioCodec` to the URL query string
        if (getAudioCodec() != null) {
            try {
                joiner.add(String.format(java.util.Locale.ROOT, "%sAudioCodec%s=%s", prefix, suffix,
                        URLEncoder.encode(String.valueOf(getAudioCodec()), "UTF-8").replaceAll("\\+", "%20")));
            } catch (UnsupportedEncodingException e) {
                // Should never happen, UTF-8 is always supported
                throw new RuntimeException(e);
            }
        }

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

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

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

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

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

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

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

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

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

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

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

        // add `TranscodeReasons` to the URL query string
        if (getTranscodeReasons() != null) {
            for (int i = 0; i < getTranscodeReasons().size(); i++) {
                if (getTranscodeReasons().get(i) != null) {
                    try {
                        joiner.add(String.format(java.util.Locale.ROOT, "%sTranscodeReasons%s%s=%s", prefix, suffix,
                                "".equals(suffix) ? ""
                                        : String.format(java.util.Locale.ROOT, "%s%d%s", containerPrefix, i,
                                                containerSuffix),
                                URLEncoder.encode(String.valueOf(getTranscodeReasons().get(i)), "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 TranscodingInfo instance;

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

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

        public TranscodingInfo.Builder audioCodec(String audioCodec) {
            this.instance.audioCodec = audioCodec;
            return this;
        }

        public TranscodingInfo.Builder videoCodec(String videoCodec) {
            this.instance.videoCodec = videoCodec;
            return this;
        }

        public TranscodingInfo.Builder container(String container) {
            this.instance.container = container;
            return this;
        }

        public TranscodingInfo.Builder isVideoDirect(Boolean isVideoDirect) {
            this.instance.isVideoDirect = isVideoDirect;
            return this;
        }

        public TranscodingInfo.Builder isAudioDirect(Boolean isAudioDirect) {
            this.instance.isAudioDirect = isAudioDirect;
            return this;
        }

        public TranscodingInfo.Builder bitrate(Integer bitrate) {
            this.instance.bitrate = bitrate;
            return this;
        }

        public TranscodingInfo.Builder framerate(Float framerate) {
            this.instance.framerate = framerate;
            return this;
        }

        public TranscodingInfo.Builder completionPercentage(Double completionPercentage) {
            this.instance.completionPercentage = completionPercentage;
            return this;
        }

        public TranscodingInfo.Builder width(Integer width) {
            this.instance.width = width;
            return this;
        }

        public TranscodingInfo.Builder height(Integer height) {
            this.instance.height = height;
            return this;
        }

        public TranscodingInfo.Builder audioChannels(Integer audioChannels) {
            this.instance.audioChannels = audioChannels;
            return this;
        }

        public TranscodingInfo.Builder hardwareAccelerationType(HardwareAccelerationType hardwareAccelerationType) {
            this.instance.hardwareAccelerationType = hardwareAccelerationType;
            return this;
        }

        public TranscodingInfo.Builder transcodeReasons(List<TranscodeReason> transcodeReasons) {
            this.instance.transcodeReasons = transcodeReasons;
            return this;
        }

        /**
         * returns a built TranscodingInfo instance.
         *
         * The builder is not reusable.
         */
        public TranscodingInfo 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 TranscodingInfo.Builder builder() {
        return new TranscodingInfo.Builder();
    }

    /**
     * Create a builder with a shallow copy of this instance.
     */
    public TranscodingInfo.Builder toBuilder() {
        return new TranscodingInfo.Builder().audioCodec(getAudioCodec()).videoCodec(getVideoCodec())
                .container(getContainer()).isVideoDirect(getIsVideoDirect()).isAudioDirect(getIsAudioDirect())
                .bitrate(getBitrate()).framerate(getFramerate()).completionPercentage(getCompletionPercentage())
                .width(getWidth()).height(getHeight()).audioChannels(getAudioChannels())
                .hardwareAccelerationType(getHardwareAccelerationType()).transcodeReasons(getTranscodeReasons());
    }
}
