// <auto-generated>
/*
 * API ebike_v1 1.0.0
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 1.0.0
 * Generated by: https://github.com/openapitools/openapi-generator.git
 */

#nullable enable

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.ComponentModel.DataAnnotations;
using Org.OpenAPITools.Client;

namespace Org.OpenAPITools.Model
{
    /// <summary>
    /// Ebike
    /// </summary>
    public partial class Ebike : IValidatableObject
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Ebike" /> class.
        /// </summary>
        /// <param name="batteryCapacity">The total ebike battery capacity in Wh</param>
        /// <param name="ebikeType">The kind of ebike</param>
        /// <param name="motorId">The database id of the ebike motor (currently unused)</param>
        /// <param name="name">The name of the ebike</param>
        /// <param name="shiftboxGearcount">The number of gears in the shiftbox</param>
        /// <param name="shiftboxManufacturer">The shiftbox manufacturer</param>
        /// <param name="tireSize">The tire size in inch</param>
        /// <param name="tireType">The kind of tires on the ebike</param>
        /// <param name="id">id (default to 0)</param>
        [JsonConstructor]
        public Ebike(int batteryCapacity, EbikeTypeEnum ebikeType, int motorId, string name, int shiftboxGearcount, ShiftboxManufacturerEnum shiftboxManufacturer, int tireSize, TireTypeEnum tireType, Option<int?> id = default)
        {
            BatteryCapacity = batteryCapacity;
            EbikeType = ebikeType;
            MotorId = motorId;
            Name = name;
            ShiftboxGearcount = shiftboxGearcount;
            ShiftboxManufacturer = shiftboxManufacturer;
            TireSize = tireSize;
            TireType = tireType;
            IdOption = id;
            OnCreated();
        }

        partial void OnCreated();

        /// <summary>
        /// The kind of ebike
        /// </summary>
        /// <value>The kind of ebike</value>
        public enum EbikeTypeEnum
        {
            /// <summary>
            /// Enum Mountain for value: mountain
            /// </summary>
            Mountain = 1,

            /// <summary>
            /// Enum Trekking for value: trekking
            /// </summary>
            Trekking = 2,

            /// <summary>
            /// Enum City for value: city
            /// </summary>
            City = 3,

            /// <summary>
            /// Enum Racing for value: racing
            /// </summary>
            Racing = 4
        }

        /// <summary>
        /// Returns a <see cref="EbikeTypeEnum"/>
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static EbikeTypeEnum EbikeTypeEnumFromString(string value)
        {
            if (value.Equals("mountain"))
                return EbikeTypeEnum.Mountain;

            if (value.Equals("trekking"))
                return EbikeTypeEnum.Trekking;

            if (value.Equals("city"))
                return EbikeTypeEnum.City;

            if (value.Equals("racing"))
                return EbikeTypeEnum.Racing;

            throw new NotImplementedException($"Could not convert value to type EbikeTypeEnum: '{value}'");
        }

        /// <summary>
        /// Returns a <see cref="EbikeTypeEnum"/>
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static EbikeTypeEnum? EbikeTypeEnumFromStringOrDefault(string value)
        {
            if (value.Equals("mountain"))
                return EbikeTypeEnum.Mountain;

            if (value.Equals("trekking"))
                return EbikeTypeEnum.Trekking;

            if (value.Equals("city"))
                return EbikeTypeEnum.City;

            if (value.Equals("racing"))
                return EbikeTypeEnum.Racing;

            return null;
        }

        /// <summary>
        /// Converts the <see cref="EbikeTypeEnum"/> to the json value
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static string EbikeTypeEnumToJsonValue(EbikeTypeEnum value)
        {
            if (value == EbikeTypeEnum.Mountain)
                return "mountain";

            if (value == EbikeTypeEnum.Trekking)
                return "trekking";

            if (value == EbikeTypeEnum.City)
                return "city";

            if (value == EbikeTypeEnum.Racing)
                return "racing";

            throw new NotImplementedException($"Value could not be handled: '{value}'");
        }

        /// <summary>
        /// The kind of ebike
        /// </summary>
        /// <value>The kind of ebike</value>
        [JsonPropertyName("ebike_type")]
        public EbikeTypeEnum EbikeType { get; set; }

        /// <summary>
        /// The shiftbox manufacturer
        /// </summary>
        /// <value>The shiftbox manufacturer</value>
        public enum ShiftboxManufacturerEnum
        {
            /// <summary>
            /// Enum Shimano for value: shimano
            /// </summary>
            Shimano = 1,

            /// <summary>
            /// Enum Sram for value: sram
            /// </summary>
            Sram = 2
        }

        /// <summary>
        /// Returns a <see cref="ShiftboxManufacturerEnum"/>
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static ShiftboxManufacturerEnum ShiftboxManufacturerEnumFromString(string value)
        {
            if (value.Equals("shimano"))
                return ShiftboxManufacturerEnum.Shimano;

            if (value.Equals("sram"))
                return ShiftboxManufacturerEnum.Sram;

            throw new NotImplementedException($"Could not convert value to type ShiftboxManufacturerEnum: '{value}'");
        }

        /// <summary>
        /// Returns a <see cref="ShiftboxManufacturerEnum"/>
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static ShiftboxManufacturerEnum? ShiftboxManufacturerEnumFromStringOrDefault(string value)
        {
            if (value.Equals("shimano"))
                return ShiftboxManufacturerEnum.Shimano;

            if (value.Equals("sram"))
                return ShiftboxManufacturerEnum.Sram;

            return null;
        }

        /// <summary>
        /// Converts the <see cref="ShiftboxManufacturerEnum"/> to the json value
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static string ShiftboxManufacturerEnumToJsonValue(ShiftboxManufacturerEnum value)
        {
            if (value == ShiftboxManufacturerEnum.Shimano)
                return "shimano";

            if (value == ShiftboxManufacturerEnum.Sram)
                return "sram";

            throw new NotImplementedException($"Value could not be handled: '{value}'");
        }

        /// <summary>
        /// The shiftbox manufacturer
        /// </summary>
        /// <value>The shiftbox manufacturer</value>
        [JsonPropertyName("shiftbox_manufacturer")]
        public ShiftboxManufacturerEnum ShiftboxManufacturer { get; set; }

        /// <summary>
        /// The kind of tires on the ebike
        /// </summary>
        /// <value>The kind of tires on the ebike</value>
        public enum TireTypeEnum
        {
            /// <summary>
            /// Enum Mountain for value: mountain
            /// </summary>
            Mountain = 1,

            /// <summary>
            /// Enum Standard for value: standard
            /// </summary>
            Standard = 2,

            /// <summary>
            /// Enum Racing for value: racing
            /// </summary>
            Racing = 3
        }

        /// <summary>
        /// Returns a <see cref="TireTypeEnum"/>
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static TireTypeEnum TireTypeEnumFromString(string value)
        {
            if (value.Equals("mountain"))
                return TireTypeEnum.Mountain;

            if (value.Equals("standard"))
                return TireTypeEnum.Standard;

            if (value.Equals("racing"))
                return TireTypeEnum.Racing;

            throw new NotImplementedException($"Could not convert value to type TireTypeEnum: '{value}'");
        }

        /// <summary>
        /// Returns a <see cref="TireTypeEnum"/>
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static TireTypeEnum? TireTypeEnumFromStringOrDefault(string value)
        {
            if (value.Equals("mountain"))
                return TireTypeEnum.Mountain;

            if (value.Equals("standard"))
                return TireTypeEnum.Standard;

            if (value.Equals("racing"))
                return TireTypeEnum.Racing;

            return null;
        }

        /// <summary>
        /// Converts the <see cref="TireTypeEnum"/> to the json value
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static string TireTypeEnumToJsonValue(TireTypeEnum value)
        {
            if (value == TireTypeEnum.Mountain)
                return "mountain";

            if (value == TireTypeEnum.Standard)
                return "standard";

            if (value == TireTypeEnum.Racing)
                return "racing";

            throw new NotImplementedException($"Value could not be handled: '{value}'");
        }

        /// <summary>
        /// The kind of tires on the ebike
        /// </summary>
        /// <value>The kind of tires on the ebike</value>
        [JsonPropertyName("tire_type")]
        public TireTypeEnum TireType { get; set; }

        /// <summary>
        /// The total ebike battery capacity in Wh
        /// </summary>
        /// <value>The total ebike battery capacity in Wh</value>
        [JsonPropertyName("battery_capacity")]
        public int BatteryCapacity { get; set; }

        /// <summary>
        /// The database id of the ebike motor (currently unused)
        /// </summary>
        /// <value>The database id of the ebike motor (currently unused)</value>
        [JsonPropertyName("motor_id")]
        public int MotorId { get; set; }

        /// <summary>
        /// The name of the ebike
        /// </summary>
        /// <value>The name of the ebike</value>
        [JsonPropertyName("name")]
        public string Name { get; set; }

        /// <summary>
        /// The number of gears in the shiftbox
        /// </summary>
        /// <value>The number of gears in the shiftbox</value>
        [JsonPropertyName("shiftbox_gearcount")]
        public int ShiftboxGearcount { get; set; }

        /// <summary>
        /// The tire size in inch
        /// </summary>
        /// <value>The tire size in inch</value>
        [JsonPropertyName("tire_size")]
        public int TireSize { get; set; }

        /// <summary>
        /// Used to track the state of Id
        /// </summary>
        [JsonIgnore]
        [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
        public Option<int?> IdOption { get; private set; }

        /// <summary>
        /// Gets or Sets Id
        /// </summary>
        [JsonPropertyName("id")]
        public int? Id { get { return this.IdOption.Value; } set { this.IdOption = new(value); } }

        /// <summary>
        /// Returns the string presentation of the object
        /// </summary>
        /// <returns>String presentation of the object</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("class Ebike {\n");
            sb.Append("  BatteryCapacity: ").Append(BatteryCapacity).Append("\n");
            sb.Append("  EbikeType: ").Append(EbikeType).Append("\n");
            sb.Append("  MotorId: ").Append(MotorId).Append("\n");
            sb.Append("  Name: ").Append(Name).Append("\n");
            sb.Append("  ShiftboxGearcount: ").Append(ShiftboxGearcount).Append("\n");
            sb.Append("  ShiftboxManufacturer: ").Append(ShiftboxManufacturer).Append("\n");
            sb.Append("  TireSize: ").Append(TireSize).Append("\n");
            sb.Append("  TireType: ").Append(TireType).Append("\n");
            sb.Append("  Id: ").Append(Id).Append("\n");
            sb.Append("}\n");
            return sb.ToString();
        }

        /// <summary>
        /// To validate all properties of the instance
        /// </summary>
        /// <param name="validationContext">Validation context</param>
        /// <returns>Validation Result</returns>
        IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
        {
            yield break;
        }
    }

    /// <summary>
    /// A Json converter for type <see cref="Ebike" />
    /// </summary>
    public class EbikeJsonConverter : JsonConverter<Ebike>
    {
        /// <summary>
        /// Deserializes json to <see cref="Ebike" />
        /// </summary>
        /// <param name="utf8JsonReader"></param>
        /// <param name="typeToConvert"></param>
        /// <param name="jsonSerializerOptions"></param>
        /// <returns></returns>
        /// <exception cref="JsonException"></exception>
        public override Ebike Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions)
        {
            int currentDepth = utf8JsonReader.CurrentDepth;

            if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray)
                throw new JsonException();

            JsonTokenType startingTokenType = utf8JsonReader.TokenType;

            Option<int?> batteryCapacity = default;
            Option<Ebike.EbikeTypeEnum?> ebikeType = default;
            Option<int?> motorId = default;
            Option<string?> name = default;
            Option<int?> shiftboxGearcount = default;
            Option<Ebike.ShiftboxManufacturerEnum?> shiftboxManufacturer = default;
            Option<int?> tireSize = default;
            Option<Ebike.TireTypeEnum?> tireType = default;
            Option<int?> id = default;

            while (utf8JsonReader.Read())
            {
                if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth)
                    break;

                if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth)
                    break;

                if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1)
                {
                    string? localVarJsonPropertyName = utf8JsonReader.GetString();
                    utf8JsonReader.Read();

                    switch (localVarJsonPropertyName)
                    {
                        case "battery_capacity":
                            batteryCapacity = new Option<int?>(utf8JsonReader.TokenType == JsonTokenType.Null ? (int?)null : utf8JsonReader.GetInt32());
                            break;
                        case "ebike_type":
                            string? ebikeTypeRawValue = utf8JsonReader.GetString();
                            if (ebikeTypeRawValue != null)
                                ebikeType = new Option<Ebike.EbikeTypeEnum?>(Ebike.EbikeTypeEnumFromStringOrDefault(ebikeTypeRawValue));
                            break;
                        case "motor_id":
                            motorId = new Option<int?>(utf8JsonReader.TokenType == JsonTokenType.Null ? (int?)null : utf8JsonReader.GetInt32());
                            break;
                        case "name":
                            name = new Option<string?>(utf8JsonReader.GetString()!);
                            break;
                        case "shiftbox_gearcount":
                            shiftboxGearcount = new Option<int?>(utf8JsonReader.TokenType == JsonTokenType.Null ? (int?)null : utf8JsonReader.GetInt32());
                            break;
                        case "shiftbox_manufacturer":
                            string? shiftboxManufacturerRawValue = utf8JsonReader.GetString();
                            if (shiftboxManufacturerRawValue != null)
                                shiftboxManufacturer = new Option<Ebike.ShiftboxManufacturerEnum?>(Ebike.ShiftboxManufacturerEnumFromStringOrDefault(shiftboxManufacturerRawValue));
                            break;
                        case "tire_size":
                            tireSize = new Option<int?>(utf8JsonReader.TokenType == JsonTokenType.Null ? (int?)null : utf8JsonReader.GetInt32());
                            break;
                        case "tire_type":
                            string? tireTypeRawValue = utf8JsonReader.GetString();
                            if (tireTypeRawValue != null)
                                tireType = new Option<Ebike.TireTypeEnum?>(Ebike.TireTypeEnumFromStringOrDefault(tireTypeRawValue));
                            break;
                        case "id":
                            id = new Option<int?>(utf8JsonReader.TokenType == JsonTokenType.Null ? (int?)null : utf8JsonReader.GetInt32());
                            break;
                        default:
                            break;
                    }
                }
            }

            if (!batteryCapacity.IsSet)
                throw new ArgumentException("Property is required for class Ebike.", nameof(batteryCapacity));

            if (!ebikeType.IsSet)
                throw new ArgumentException("Property is required for class Ebike.", nameof(ebikeType));

            if (!motorId.IsSet)
                throw new ArgumentException("Property is required for class Ebike.", nameof(motorId));

            if (!name.IsSet)
                throw new ArgumentException("Property is required for class Ebike.", nameof(name));

            if (!shiftboxGearcount.IsSet)
                throw new ArgumentException("Property is required for class Ebike.", nameof(shiftboxGearcount));

            if (!shiftboxManufacturer.IsSet)
                throw new ArgumentException("Property is required for class Ebike.", nameof(shiftboxManufacturer));

            if (!tireSize.IsSet)
                throw new ArgumentException("Property is required for class Ebike.", nameof(tireSize));

            if (!tireType.IsSet)
                throw new ArgumentException("Property is required for class Ebike.", nameof(tireType));

            if (batteryCapacity.IsSet && batteryCapacity.Value == null)
                throw new ArgumentNullException(nameof(batteryCapacity), "Property is not nullable for class Ebike.");

            if (ebikeType.IsSet && ebikeType.Value == null)
                throw new ArgumentNullException(nameof(ebikeType), "Property is not nullable for class Ebike.");

            if (motorId.IsSet && motorId.Value == null)
                throw new ArgumentNullException(nameof(motorId), "Property is not nullable for class Ebike.");

            if (name.IsSet && name.Value == null)
                throw new ArgumentNullException(nameof(name), "Property is not nullable for class Ebike.");

            if (shiftboxGearcount.IsSet && shiftboxGearcount.Value == null)
                throw new ArgumentNullException(nameof(shiftboxGearcount), "Property is not nullable for class Ebike.");

            if (shiftboxManufacturer.IsSet && shiftboxManufacturer.Value == null)
                throw new ArgumentNullException(nameof(shiftboxManufacturer), "Property is not nullable for class Ebike.");

            if (tireSize.IsSet && tireSize.Value == null)
                throw new ArgumentNullException(nameof(tireSize), "Property is not nullable for class Ebike.");

            if (tireType.IsSet && tireType.Value == null)
                throw new ArgumentNullException(nameof(tireType), "Property is not nullable for class Ebike.");

            if (id.IsSet && id.Value == null)
                throw new ArgumentNullException(nameof(id), "Property is not nullable for class Ebike.");

            return new Ebike(batteryCapacity.Value!.Value!, ebikeType.Value!.Value!, motorId.Value!.Value!, name.Value!, shiftboxGearcount.Value!.Value!, shiftboxManufacturer.Value!.Value!, tireSize.Value!.Value!, tireType.Value!.Value!, id);
        }

        /// <summary>
        /// Serializes a <see cref="Ebike" />
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="ebike"></param>
        /// <param name="jsonSerializerOptions"></param>
        /// <exception cref="NotImplementedException"></exception>
        public override void Write(Utf8JsonWriter writer, Ebike ebike, JsonSerializerOptions jsonSerializerOptions)
        {
            writer.WriteStartObject();

            WriteProperties(writer, ebike, jsonSerializerOptions);
            writer.WriteEndObject();
        }

        /// <summary>
        /// Serializes the properties of <see cref="Ebike" />
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="ebike"></param>
        /// <param name="jsonSerializerOptions"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void WriteProperties(Utf8JsonWriter writer, Ebike ebike, JsonSerializerOptions jsonSerializerOptions)
        {
            if (ebike.Name == null)
                throw new ArgumentNullException(nameof(ebike.Name), "Property is required for class Ebike.");

            writer.WriteNumber("battery_capacity", ebike.BatteryCapacity);

            var ebikeTypeRawValue = Ebike.EbikeTypeEnumToJsonValue(ebike.EbikeType);
            writer.WriteString("ebike_type", ebikeTypeRawValue);
            writer.WriteNumber("motor_id", ebike.MotorId);

            writer.WriteString("name", ebike.Name);

            writer.WriteNumber("shiftbox_gearcount", ebike.ShiftboxGearcount);

            var shiftboxManufacturerRawValue = Ebike.ShiftboxManufacturerEnumToJsonValue(ebike.ShiftboxManufacturer);
            writer.WriteString("shiftbox_manufacturer", shiftboxManufacturerRawValue);
            writer.WriteNumber("tire_size", ebike.TireSize);

            var tireTypeRawValue = Ebike.TireTypeEnumToJsonValue(ebike.TireType);
            writer.WriteString("tire_type", tireTypeRawValue);
            if (ebike.IdOption.IsSet)
                writer.WriteNumber("id", ebike.IdOption.Value!.Value);
        }
    }
}
