{-# LANGUAGE OverloadedStrings #-}

module Ebay.Types.Shipping
    ( ShippingDetails (..)
    , xpShippingDetails

    , ShippingTypeCode (..)
    , xpShippingTypeCode

    , ShippingServiceOptions (..)
    , xpShippingServiceOptions
    ) where

import           Data.Text                       as T
import           Data.XML.Pickle
import           Data.XML.Types
import           GHC.Read
import           Text.ParserCombinators.ReadPrec
import           Text.Read.Lex                   as L

import           Ebay.Types

data ShippingDetails = ShippingDetails
        { shippingType           :: Maybe ShippingTypeCode
        , shippingServiceOptions :: [ShippingServiceOptions]
        } deriving (Eq, Show)

xpShippingDetails :: PU [Node] ShippingDetails
xpShippingDetails =
    xpWrap (\(a, b) -> ShippingDetails a b)
           (\(ShippingDetails a b) -> (a, b)) $
    xp2Tuple
        (xpOption $ xpElemNodes "{urn:ebay:apis:eBLBaseComponents}ShippingType" $
            xpContent xpShippingTypeCode)
        (xpList $ xpElemNodes "{urn:ebay:apis:eBLBaseComponents}ShippingServiceOptions" $
            xpShippingServiceOptions)

----

data ShippingTypeCode = STCalculated | STCalculatedDomesticFlatInternational | STCustomCode
                      | STFlat | STFlatDomesticCalculatedInternational | STFree | STFreight
                      | STFreightFlat | STNotSpecified
                      deriving (Eq)

instance Show ShippingTypeCode where
    show STCalculated                           = "Calculated"
    show STCalculatedDomesticFlatInternational  = "CalculatedDomesticFlatInternational"
    show STCustomCode                           = "CustomCode"
    show STFlat                                 = "Flat"
    show STFlatDomesticCalculatedInternational  = "FlatDomesticCalculatedInternational"
    show STFree                                 = "Free"
    show STFreight                              = "Freight"
    show STFreightFlat                          = "FreightFlat"
    show STNotSpecified                         = "NotSpecified"

instance Read ShippingTypeCode where
    readPrec = parens $ do
        L.Ident s <- lexP
        case s of "Calculated"                          -> return STCalculated
                  "CalculatedDomesticFlatInternational" -> return STCalculatedDomesticFlatInternational
                  "CustomCode"                          -> return STCustomCode
                  "Flat"                                -> return STFlat
                  "FlatDomesticCalculatedInternational" -> return STFlatDomesticCalculatedInternational
                  "Free"                                -> return STFree
                  "Freight"                             -> return STFreight
                  "FreightFlat"                         -> return STFreightFlat
                  "NotSpecified"                        -> return STNotSpecified
                  _                                     -> pfail

xpShippingTypeCode :: PU Text ShippingTypeCode
xpShippingTypeCode = xpPrim

----

data ShippingServiceOptions = ShippingServiceOptions
        { servicePriority :: Maybe Int
        , serviceShipper  :: Maybe Text
        , serviceCost     :: Maybe Double
        } deriving (Eq, Show)

xpShippingServiceOptions :: PU [Node] ShippingServiceOptions
xpShippingServiceOptions =
    xpWrap (\(a, b, c) -> ShippingServiceOptions a b c)
           (\(ShippingServiceOptions a b c) -> (a, b, c)) $
    xp3Tuple
        (xpOption $ xpElemNodes "{urn:ebay:apis:eBLBaseComponents}ShippingServicePriority" $
            xpContent xpPrim)
        (xpOption $ xpElemText "{urn:ebay:apis:eBLBaseComponents}ShippingService")
        (xpOption $ xpElemNodes "{urn:ebay:apis:eBLBaseComponents}ShippingServiceCost" $
            xpContent $ xpPrim)
