using System;
using System.Collections.Generic;
using System.Text;

// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using QuickType;
//
//    var welcome = Welcome.FromJson(jsonString);

namespace TyphoonApi
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class Welcome
    {
        [JsonProperty("?xml")]
        public Xml Xml { get; set; }

        [JsonProperty("alert")]
        public Alert Alert { get; set; }
    }

    public partial class Alert
    {
        [JsonProperty("@xmlns")]
        public string Xmlns { get; set; }

        [JsonProperty("identifier")]
        public string Identifier { get; set; }

        [JsonProperty("sender")]
        public string Sender { get; set; }

        [JsonProperty("sent")]
        public DateTimeOffset Sent { get; set; }

        [JsonProperty("status")]
        public string Status { get; set; }

        [JsonProperty("msgType")]
        public string MsgType { get; set; }

        [JsonProperty("scope")]
        public string Scope { get; set; }

        [JsonProperty("references")]
        public string References { get; set; }

        [JsonProperty("info")]
        public Info Info { get; set; }
    }

    public partial class Info
    {
        [JsonProperty("language")]
        public string Language { get; set; }

        [JsonProperty("category")]
        public string Category { get; set; }

        [JsonProperty("event")]
        public string Event { get; set; }

        [JsonProperty("responseType")]
        public string ResponseType { get; set; }

        [JsonProperty("urgency")]
        public string Urgency { get; set; }

        [JsonProperty("severity")]
        public string Severity { get; set; }

        [JsonProperty("certainty")]
        public string Certainty { get; set; }

        [JsonProperty("eventCode")]
        public EventCode EventCode { get; set; }

        [JsonProperty("effective")]
        public DateTimeOffset Effective { get; set; }

        [JsonProperty("onset")]
        public DateTimeOffset Onset { get; set; }

        [JsonProperty("expires")]
        public DateTimeOffset Expires { get; set; }

        [JsonProperty("senderName")]
        public string SenderName { get; set; }

        [JsonProperty("headline")]
        public string Headline { get; set; }

        [JsonProperty("description")]
        public Description Description { get; set; }

        [JsonProperty("web")]
        public Uri Web { get; set; }

        [JsonProperty("parameter")]
        public EventCode[] Parameter { get; set; }

        [JsonProperty("area")]
        public Area[] Area { get; set; }
    }

    public partial class Area
    {
        [JsonProperty("areaDesc")]
        public string AreaDesc { get; set; }

        [JsonProperty("polygon")]
        public string Polygon { get; set; }
    }

    public partial class Description
    {
        [JsonProperty("typhoon-info")]
        public TyphoonInfo TyphoonInfo { get; set; }

        [JsonProperty("section")]
        public DescriptionSection[] Section { get; set; }
    }

    public partial class DescriptionSection
    {
        [JsonProperty("@title")]
        public string Title { get; set; }

        [JsonProperty("#text")]
        public string Text { get; set; }
    }

    public partial class TyphoonInfo
    {
        [JsonProperty("section")]
        public TyphoonInfoSection[] Section { get; set; }
    }

    public partial class TyphoonInfoSection
    {
        [JsonProperty("@title")]
        public string Title { get; set; }

        [JsonProperty("#text", NullValueHandling = NullValueHandling.Ignore)]
        public string Text { get; set; }

        [JsonProperty("typhoon_name", NullValueHandling = NullValueHandling.Ignore)]
        public string TyphoonName { get; set; }

        [JsonProperty("cwb_typhoon_name", NullValueHandling = NullValueHandling.Ignore)]
        public string CwbTyphoonName { get; set; }

        [JsonProperty("analysis", NullValueHandling = NullValueHandling.Ignore)]
        public Analysis Analysis { get; set; }

        [JsonProperty("prediction", NullValueHandling = NullValueHandling.Ignore)]
        public Analysis Prediction { get; set; }
    }

    public partial class Analysis
    {
        [JsonProperty("time")]
        public DateTimeOffset Time { get; set; }

        [JsonProperty("position")]
        public string Position { get; set; }

        [JsonProperty("max_winds")]
        public Gust MaxWinds { get; set; }

        [JsonProperty("gust")]
        public Gust Gust { get; set; }

        [JsonProperty("pressure")]
        public Gust Pressure { get; set; }

        [JsonProperty("radius_of_15mps")]
        public Gust RadiusOf15Mps { get; set; }

        [JsonProperty("scale", NullValueHandling = NullValueHandling.Ignore)]
        public Scale[] Scale { get; set; }
    }

    public partial class Gust
    {
        [JsonProperty("@unit")]
        public string Unit { get; set; }

        [JsonProperty("#text")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long Text { get; set; }
    }

    public partial class Scale
    {
        [JsonProperty("@lang")]
        public string Lang { get; set; }

        [JsonProperty("#text")]
        public string Text { get; set; }
    }

    public partial class EventCode
    {
        [JsonProperty("valueName")]
        public string ValueName { get; set; }

        [JsonProperty("value")]
        public string Value { get; set; }
    }

    public partial class Xml
    {
        [JsonProperty("@version")]
        public string Version { get; set; }

        [JsonProperty("@encoding")]
        public string Encoding { get; set; }
    }

    public partial class Welcome
    {
        public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }

    internal class ParseStringConverter : JsonConverter
    {
        public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return null;
            var value = serializer.Deserialize<string>(reader);
            long l;
            if (Int64.TryParse(value, out l))
            {
                return l;
            }
            throw new Exception("Cannot unmarshal type long");
        }

        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
        {
            if (untypedValue == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
            var value = (long)untypedValue;
            serializer.Serialize(writer, value.ToString());
            return;
        }

        public static readonly ParseStringConverter Singleton = new ParseStringConverter();
    }
}