//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Requests
{
    using LukeHagar.PlexAPI.SDK.Models.Requests;
    using LukeHagar.PlexAPI.SDK.Utils;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Numerics;
    using System.Reflection;
    

    public class GetAllMediaLibraryLibraryOptimizedForStreamingType
    {
        private GetAllMediaLibraryLibraryOptimizedForStreamingType(string value) { Value = value; }

        public string Value { get; private set; }
        public static GetAllMediaLibraryLibraryOptimizedForStreamingType GetAllMediaLibraryOptimizedForStreaming1 { get { return new GetAllMediaLibraryLibraryOptimizedForStreamingType("get-all-media-library_optimizedForStreaming_1"); } }
        
        public static GetAllMediaLibraryLibraryOptimizedForStreamingType Boolean { get { return new GetAllMediaLibraryLibraryOptimizedForStreamingType("boolean"); } }
        
        public static GetAllMediaLibraryLibraryOptimizedForStreamingType Null { get { return new GetAllMediaLibraryLibraryOptimizedForStreamingType("null"); } }

        public override string ToString() { return Value; }
        public static implicit operator String(GetAllMediaLibraryLibraryOptimizedForStreamingType v) { return v.Value; }
        public static GetAllMediaLibraryLibraryOptimizedForStreamingType FromString(string v) {
            switch(v) {
                case "get-all-media-library_optimizedForStreaming_1": return GetAllMediaLibraryOptimizedForStreaming1;
                case "boolean": return Boolean;
                case "null": return Null;
                default: throw new ArgumentException("Invalid value for GetAllMediaLibraryLibraryOptimizedForStreamingType");
            }
        }
        public override bool Equals(object? obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }
            return Value.Equals(((GetAllMediaLibraryLibraryOptimizedForStreamingType)obj).Value);
        }

        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }
    }


    /// <summary>
    /// Has this media been optimized for streaming. NOTE: This can be 0, 1, false or true
    /// </summary>
    [JsonConverter(typeof(GetAllMediaLibraryLibraryOptimizedForStreaming.GetAllMediaLibraryLibraryOptimizedForStreamingConverter))]
    public class GetAllMediaLibraryLibraryOptimizedForStreaming {
        public GetAllMediaLibraryLibraryOptimizedForStreaming(GetAllMediaLibraryLibraryOptimizedForStreamingType type) {
            Type = type;
        }

        [SpeakeasyMetadata("form:explode=true")]
        public GetAllMediaLibraryOptimizedForStreaming1? GetAllMediaLibraryOptimizedForStreaming1 { get; set; }

        [SpeakeasyMetadata("form:explode=true")]
        public bool? Boolean { get; set; }

        public GetAllMediaLibraryLibraryOptimizedForStreamingType Type { get; set; }


        public static GetAllMediaLibraryLibraryOptimizedForStreaming CreateGetAllMediaLibraryOptimizedForStreaming1(GetAllMediaLibraryOptimizedForStreaming1 getAllMediaLibraryOptimizedForStreaming1) {
            GetAllMediaLibraryLibraryOptimizedForStreamingType typ = GetAllMediaLibraryLibraryOptimizedForStreamingType.GetAllMediaLibraryOptimizedForStreaming1;

            GetAllMediaLibraryLibraryOptimizedForStreaming res = new GetAllMediaLibraryLibraryOptimizedForStreaming(typ);
            res.GetAllMediaLibraryOptimizedForStreaming1 = getAllMediaLibraryOptimizedForStreaming1;
            return res;
        }

        public static GetAllMediaLibraryLibraryOptimizedForStreaming CreateBoolean(bool boolean) {
            GetAllMediaLibraryLibraryOptimizedForStreamingType typ = GetAllMediaLibraryLibraryOptimizedForStreamingType.Boolean;

            GetAllMediaLibraryLibraryOptimizedForStreaming res = new GetAllMediaLibraryLibraryOptimizedForStreaming(typ);
            res.Boolean = boolean;
            return res;
        }

        public static GetAllMediaLibraryLibraryOptimizedForStreaming CreateNull() {
            GetAllMediaLibraryLibraryOptimizedForStreamingType typ = GetAllMediaLibraryLibraryOptimizedForStreamingType.Null;
            return new GetAllMediaLibraryLibraryOptimizedForStreaming(typ);
        }

        public class GetAllMediaLibraryLibraryOptimizedForStreamingConverter : JsonConverter
        {

            public override bool CanConvert(System.Type objectType) => objectType == typeof(GetAllMediaLibraryLibraryOptimizedForStreaming);

            public override bool CanRead => true;

            public override object? ReadJson(JsonReader reader, System.Type objectType, object? existingValue, JsonSerializer serializer)
            {
                var json = JRaw.Create(reader).ToString();
                if (json == "null")
                {
                    return null;
                }

                var fallbackCandidates = new List<(System.Type, object, string)>();

                try
                {
                    return new GetAllMediaLibraryLibraryOptimizedForStreaming(GetAllMediaLibraryLibraryOptimizedForStreamingType.GetAllMediaLibraryOptimizedForStreaming1)
                    {
                        GetAllMediaLibraryOptimizedForStreaming1 = ResponseBodyDeserializer.DeserializeUndiscriminatedUnionMember<GetAllMediaLibraryOptimizedForStreaming1>(json)
                    };
                }
                catch (ResponseBodyDeserializer.MissingMemberException)
                {
                    fallbackCandidates.Add((typeof(GetAllMediaLibraryOptimizedForStreaming1), new GetAllMediaLibraryLibraryOptimizedForStreaming(GetAllMediaLibraryLibraryOptimizedForStreamingType.GetAllMediaLibraryOptimizedForStreaming1), "GetAllMediaLibraryOptimizedForStreaming1"));
                }
                catch (ResponseBodyDeserializer.DeserializationException)
                {
                    // try next option
                }
                catch (Exception)
                {
                    throw;
                }

                try
                {
                    var converted = Convert.ToBoolean(json);
                    return new GetAllMediaLibraryLibraryOptimizedForStreaming(GetAllMediaLibraryLibraryOptimizedForStreamingType.Boolean)
                    {
                        Boolean = converted
                    };
                }
                catch (System.FormatException)
                {
                    // try next option
                }

                if (fallbackCandidates.Count > 0)
                {
                    fallbackCandidates.Sort((a, b) => ResponseBodyDeserializer.CompareFallbackCandidates(a.Item1, b.Item1, json));
                    foreach(var (deserializationType, returnObject, propertyName) in fallbackCandidates)
                    {
                        try
                        {
                            return ResponseBodyDeserializer.DeserializeUndiscriminatedUnionFallback(deserializationType, returnObject, propertyName, json);
                        }
                        catch (ResponseBodyDeserializer.DeserializationException)
                        {
                            // try next fallback option
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                }

                throw new InvalidOperationException("Could not deserialize into any supported types.");
            }

            public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
            {
                if (value == null) {
                    writer.WriteRawValue("null");
                    return;
                }
                GetAllMediaLibraryLibraryOptimizedForStreaming res = (GetAllMediaLibraryLibraryOptimizedForStreaming)value;
                if (GetAllMediaLibraryLibraryOptimizedForStreamingType.FromString(res.Type).Equals(GetAllMediaLibraryLibraryOptimizedForStreamingType.Null))
                {
                    writer.WriteRawValue("null");
                    return;
                }
                if (res.GetAllMediaLibraryOptimizedForStreaming1 != null)
                {
                    writer.WriteRawValue(Utilities.SerializeJSON(res.GetAllMediaLibraryOptimizedForStreaming1));
                    return;
                }
                if (res.Boolean != null)
                {
                    writer.WriteRawValue(Utilities.SerializeJSON(res.Boolean));
                    return;
                }

            }

        }

    }
}