
Imports System
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Converters
Imports System.Runtime.CompilerServices

Namespace cModalENS

    ''' <summary>
    ''' CreateEnsDeclaration
    ''' </summary>
    Partial Public Class ApidogModel
        <JsonProperty("manifesto")>
        Public Property Manifesto As Manifesto
    End Class

    Partial Public Class Manifesto
        <JsonProperty("ncts_json_data")>
        Public Property NctsJsonData As NctsJsonData
    End Class

    Partial Public Class NctsJsonData
        ''' <summary>
        ''' Code of the arrival customs
        ''' </summary>
        <JsonProperty("arrival_custom_code")>
        Public Property ArrivalCustomCode As String

        ''' <summary>
        ''' Carrier Address
        ''' </summary>
        <JsonProperty("carrier_address")>
        Public Property CarrierAddress As String

        ''' <summary>
        ''' Carrier City
        ''' </summary>
        <JsonProperty("carrier_city")>
        Public Property CarrierCity As String

        ''' <summary>
        ''' Carrier Country Code
        ''' </summary>
        <JsonProperty("carrier_country_id")>
        Public Property CarrierCountryId As String

        ''' <summary>
        ''' Carrier Name
        ''' </summary>
        <JsonProperty("carrier_name")>
        Public Property CarrierName As String

        ''' <summary>
        ''' Carrier Postcode
        ''' </summary>
        <JsonProperty("carrier_postcode")>
        Public Property CarrierPostcode As String

        ''' <summary>
        ''' Carrier Tax No
        ''' </summary>
        <JsonProperty("carrier_taxno")>
        Public Property CarrierTaxno As String

        ''' <summary>
        ''' Container (if cargo is containerized)
        ''' </summary>
        <JsonProperty("container", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property Container As String

        ''' <summary>
        ''' Code of the departure customs
        ''' </summary>
        <JsonProperty("departure_custom_code")>
        Public Property DepartureCustomCode As String

        ''' <summary>
        ''' Destination Country Code
        ''' </summary>
        <JsonProperty("destination_country_id")>
        Public Property DestinationCountryId As String

        ''' <summary>
        ''' Dispatch Country Code
        ''' </summary>
        <JsonProperty("dispatch_country_id")>
        Public Property DispatchCountryId As String

        ''' <summary>
        ''' Type of the declaration. Should be "ENS".
        ''' </summary>
        <JsonProperty("doc_type")>
        Public Property DocType As DocType

        ''' <summary>
        ''' Voyage NO
        ''' </summary>
        <JsonProperty("ens_voyage_no", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property EnsVoyageNo As String

        <JsonProperty("goods_attributes")>
        Public Property GoodsAttributes As GoodsAttribute()

        ''' <summary>
        ''' Departure Place
        ''' </summary>
        <JsonProperty("load_place")>
        Public Property LoadPlace As String

        ''' <summary>
        ''' RORO Operator
        ''' </summary>
        <JsonProperty("roro_operator_code", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property RoroOperatorCode As String

        ''' <summary>
        ''' Seal NO
        ''' </summary>
        <JsonProperty("seal_info", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property SealInfo As String

        ''' <summary>
        ''' Trailer Code/Plate
        ''' </summary>
        <JsonProperty("trailer_code", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property TrailerCode As String

        ''' <summary>
        ''' Trailer Country Code
        ''' </summary>
        <JsonProperty("trailer_coun", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property TrailerCoun As String

        ''' <summary>
        ''' Transit Method
        ''' </summary>
        <JsonProperty("trans_method")>
        Public Property TransMethod As TransMethod

        ''' <summary>
        ''' Transit Countries (write it for every transit country)
        ''' </summary>
        <JsonProperty("transit_countries_attributes", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property TransitCountriesAttributes As TransitCountriesAttribute()

        ''' <summary>
        ''' Destination Place
        ''' </summary>
        <JsonProperty("unload_place")>
        Public Property UnloadPlace As String

        ''' <summary>
        ''' Vehicle Code/Plate
        ''' </summary>
        <JsonProperty("vehicle_code")>
        Public Property VehicleCode As String

        ''' <summary>
        ''' Vehicle Country Code
        ''' </summary>
        <JsonProperty("vehicle_coun")>
        Public Property VehicleCoun As String
    End Class

    Partial Public Class GoodsAttribute
        ''' <summary>
        ''' Gross weight of goods
        ''' </summary>
        <JsonProperty("brut_wg", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property BrutWg As Double?

        ''' <summary>
        ''' Goods description
        ''' </summary>
        <JsonProperty("commodity")>
        Public Property Commodity As String

        ''' <summary>
        ''' Consignee's address
        ''' </summary>
        <JsonProperty("consignee_address")>
        Public Property ConsigneeAddress As String

        ''' <summary>
        ''' Consignee's city
        ''' </summary>
        <JsonProperty("consignee_city")>
        Public Property ConsigneeCity As String

        ''' <summary>
        ''' Consignee's country code
        ''' </summary>
        <JsonProperty("consignee_country_id")>
        Public Property ConsigneeCountryId As String

        ''' <summary>
        ''' Consignee's name
        ''' </summary>
        <JsonProperty("consignee_name")>
        Public Property ConsigneeName As String

        ''' <summary>
        ''' Consignee's postcode
        ''' </summary>
        <JsonProperty("consignee_postcode")>
        Public Property ConsigneePostcode As String

        ''' <summary>
        ''' Consignee's tax number
        ''' </summary>
        <JsonProperty("consignee_taxno")>
        Public Property ConsigneeTaxno As String

        ''' <summary>
        ''' Container number
        ''' </summary>
        <JsonProperty("container_no", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property ContainerNo As String

        ''' <summary>
        ''' HS code for the goods
        ''' </summary>
        <JsonProperty("gtip_code")>
        Public Property GtipCode As String

        ''' <summary>
        ''' Invoice amount
        ''' </summary>
        <JsonProperty("invoice_amount")>
        Public Property InvoiceAmount As Double

        ''' <summary>
        ''' Net weight of goods
        ''' </summary>
        <JsonProperty("net_wg", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property NetWg As Double?

        ''' <summary>
        ''' Packaging details
        ''' </summary>
        <JsonProperty("packs_attributes", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property PacksAttributes As PacksAttribute()

        ''' <summary>
        ''' Related documents
        ''' </summary>
        <JsonProperty("produced_documents_attributes", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property ProducedDocumentsAttributes As ProducedDocumentsAttribute()

        ''' <summary>
        ''' Sender's address
        ''' </summary>
        <JsonProperty("sender_address")>
        Public Property SenderAddress As String

        ''' <summary>
        ''' Sender's city
        ''' </summary>
        <JsonProperty("sender_city")>
        Public Property SenderCity As String

        ''' <summary>
        ''' Sender's country code
        ''' </summary>
        <JsonProperty("sender_country_id")>
        Public Property SenderCountryId As String

        ''' <summary>
        ''' Sender's name
        ''' </summary>
        <JsonProperty("sender_name")>
        Public Property SenderName As String

        ''' <summary>
        ''' Sender's postcode
        ''' </summary>
        <JsonProperty("sender_postcode")>
        Public Property SenderPostcode As String

        ''' <summary>
        ''' Sender's tax number
        ''' </summary>
        <JsonProperty("sender_taxno")>
        Public Property SenderTaxno As String
    End Class

    Partial Public Class PacksAttribute
        ''' <summary>
        ''' Packaging notes
        ''' </summary>
        <JsonProperty("notes", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property Notes As String

        ''' <summary>
        ''' Number of packages
        ''' </summary>
        <JsonProperty("pack_count")>
        Public Property PackCount As Double

        ''' <summary>
        ''' Pack Code
        ''' </summary>
        <JsonProperty("pack_type")>
        Public Property PackType As String
    End Class

    Partial Public Class ProducedDocumentsAttribute
        ''' <summary>
        ''' Document code
        ''' </summary>
        <JsonProperty("code")>
        Public Property Code As String

        ''' <summary>
        ''' Line NO
        ''' </summary>
        <JsonProperty("quantity", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property Quantity As Double?

        ''' <summary>
        ''' Additonal Information
        ''' </summary>
        <JsonProperty("reason", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property Reason As String

        ''' <summary>
        ''' Document reference
        ''' </summary>
        <JsonProperty("reference", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property Reference As String

        ''' <summary>
        ''' Document Type
        ''' </summary>
        <JsonProperty("scope", NullValueHandling:=NullValueHandling.Ignore)>
        Public Property Scope As String
    End Class

    Partial Public Class TransitCountriesAttribute
        ''' <summary>
        ''' Country Code
        ''' </summary>
        <JsonProperty("country_id")>
        Public Property CountryId As String
    End Class

    ''' <summary>
    ''' Type of the declaration. Should be "ENS".
    ''' </summary>
    Public Enum DocType
        Ens
    End Enum

    ''' <summary>
    ''' Transit Method
    ''' </summary>
    Public Enum TransMethod
        Air
        Rail
        Road
        RoroAccompanied
        RoroUnaccompanied
    End Enum

    Partial Public Class ApidogModel
        Public Shared Function FromJson(json As String) As ApidogModel
            Return JsonConvert.DeserializeObject(Of ApidogModel)(json, Settings)
        End Function
    End Class

    Public Module Serialize
        <Extension()>
        Public Function ToJson(Meself As ApidogModel) As String
            Return JsonConvert.SerializeObject(Meself, Settings)
        End Function
    End Module

    Friend Module Converter
        Public ReadOnly Settings As JsonSerializerSettings = New JsonSerializerSettings With {
    .MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
    .DateParseHandling = DateParseHandling.None
}
    End Module

    Friend Class DocTypeConverter
        Inherits JsonConverter
        Public Overrides Function CanConvert(t As Type) As Boolean
            Return t Is GetType(DocType) OrElse t Is GetType(DocType?)
        End Function

        Public Overrides Function ReadJson(reader As JsonReader, t As Type, existingValue As Object, serializer As JsonSerializer) As Object
            If reader.TokenType = JsonToken.Null Then Return Nothing
            Dim value = serializer.Deserialize(Of String)(reader)
            If value Is "ENS" Then
                Return DocType.Ens
            End If
            Throw New Exception("Cannot unmarshal type DocType")
        End Function

        Public Overrides Sub WriteJson(writer As JsonWriter, untypedValue As Object, serializer As JsonSerializer)
            If untypedValue Is Nothing Then
                serializer.Serialize(writer, Nothing)
                Return
            End If
            Dim value = CType(untypedValue, DocType)
            If value = DocType.Ens Then
                serializer.Serialize(writer, "ENS")
                Return
            End If
            Throw New Exception("Cannot marshal type DocType")
        End Sub

        Public Shared ReadOnly Singleton As DocTypeConverter = New DocTypeConverter()
    End Class

    Friend Class TransMethodConverter
        Inherits JsonConverter
        Public Overrides Function CanConvert(t As Type) As Boolean
            Return t Is GetType(TransMethod) OrElse t Is GetType(TransMethod?)
        End Function

        Public Overrides Function ReadJson(reader As JsonReader, t As Type, existingValue As Object, serializer As JsonSerializer) As Object
            If reader.TokenType = JsonToken.Null Then Return Nothing
            Dim value = serializer.Deserialize(Of String)(reader)
            Select Case value
                Case "air"
                    Return TransMethod.Air
                Case "rail"
                    Return TransMethod.Rail
                Case "road"
                    Return TransMethod.Road
                Case "roro_accompanied"
                    Return TransMethod.RoroAccompanied
                Case "roro_unaccompanied"
                    Return TransMethod.RoroUnaccompanied
            End Select
            Throw New Exception("Cannot unmarshal type TransMethod")
        End Function

        Public Overrides Sub WriteJson(writer As JsonWriter, untypedValue As Object, serializer As JsonSerializer)
            If untypedValue Is Nothing Then
                serializer.Serialize(writer, Nothing)
                Return
            End If
            Dim value = CType(untypedValue, TransMethod)
            Select Case value
                Case TransMethod.Air
                    serializer.Serialize(writer, "air")
                    Return
                Case TransMethod.Rail
                    serializer.Serialize(writer, "rail")
                    Return
                Case TransMethod.Road
                    serializer.Serialize(writer, "road")
                    Return
                Case TransMethod.RoroAccompanied
                    serializer.Serialize(writer, "roro_accompanied")
                    Return
                Case TransMethod.RoroUnaccompanied
                    serializer.Serialize(writer, "roro_unaccompanied")
                    Return
            End Select
            Throw New Exception("Cannot marshal type TransMethod")
        End Sub

        Public Shared ReadOnly Singleton As TransMethodConverter = New TransMethodConverter()
    End Class
End Namespace
