{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}

module Data.Aviation.Stratux.Types.NetworkConnection(
  NetworkConnection(..)
, HasNetworkConnection(..)
) where

import Control.Applicative((<*>))
import Control.Lens(makeClassy)
import Data.Aeson(FromJSON(parseJSON), ToJSON(toJSON), (.:), (.=), object, withObject)
import Data.Bool(Bool)
import Data.Eq(Eq)
import Data.Functor((<$>))
import Data.Int(Int)
import Data.Maybe(Maybe)
import Data.Ord(Ord)
import Data.String(String)
import Data.Time(UTCTime)
import Data.Word(Word8)
import Prelude(Show)

-- $setup
-- >>> :set -XOverloadedStrings
-- >>> import Control.Lens
-- >>> import Data.Aeson(decode, encode)
-- >>> import Data.Maybe(Maybe)
-- >>> import Data.Time
-- >>> import Prelude

data NetworkConnection =
  NetworkConnection {
    _conn :: Maybe String -- net.UDPConn
  , _ip :: String
  , _port :: Int
  , _capability :: Word8
  , _lastUnreachable :: UTCTime
  , _sleepFlag :: Bool
  } deriving (Eq, Ord, Show)

makeClassy ''NetworkConnection

-- |
--
-- >>> decode "{\"Conn\":null,\"Ip\":\"\",\"Port\":4000,\"Capability\":5,\"LastUnreachable\":\"0001-01-01T00:00:00Z\",\"SleepFlag\":false}" :: Maybe NetworkConnection
-- Just (NetworkConnection {_conn = Nothing, _ip = "", _port = 4000, _capability = 5, _lastUnreachable = 0001-01-01 00:00:00 UTC, _sleepFlag = False})
instance FromJSON NetworkConnection where
  parseJSON =
    withObject "NetworkConnection" (\x ->
      NetworkConnection <$>
        x .: "Conn" <*>
        x .: "Ip" <*>
        x .: "Port" <*>
        x .: "Capability" <*>
        x .: "LastUnreachable" <*>
        x .: "SleepFlag")

-- |
--
-- >>> encode (NetworkConnection Nothing "" 4000 5 (UTCTime (fromGregorian 1 1 1) 597) False)
-- "{\"Ip\":\"\",\"Conn\":null,\"Capability\":5,\"SleepFlag\":false,\"LastUnreachable\":\"0001-01-01T00:09:57Z\",\"Port\":4000}"
instance ToJSON NetworkConnection where
  toJSON (NetworkConnection conn_ ip_ port_ capability_ lastUnreachable_ sleepFlag_) =
    object [
      "Conn" .= conn_
    , "Ip" .= ip_
    , "Port" .= port_
    , "Capability" .= capability_
    , "LastUnreachable" .= lastUnreachable_
    , "SleepFlag" .= sleepFlag_
    ]