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

module Data.Aviation.Stratux.Types.Status(
  Status(..)
, HasStatus(..)
) where

import Control.Applicative((<*>), (<$>))
import Data.Bool(Bool)
import Data.Eq(Eq)
import Data.Int(Int, Int64)
import Data.Ord(Ord)
import Data.String(String)
import Data.Time(UTCTime)
import Control.Lens(makeClassy)
import Data.Aeson(FromJSON(parseJSON), ToJSON(toJSON), (.=), (.:), object, withObject)
import Data.Aviation.Stratux.Types.GpsSolution(GpsSolution)
import Data.Aviation.Stratux.Types.UTCTimes(HasUTCTimes(utcTimes))
import Prelude(Show, Float)

-- $setup
-- >>> :set -XOverloadedStrings
-- >>> import Control.Lens
-- >>> import Data.Aeson(decode, encode)
-- >>> import Data.Maybe(Maybe)
-- >>> import Data.Time
-- >>> import Data.Bool
-- >>> import Data.Aviation.Stratux.Types.GpsSolution

-- https://i.imgur.com/i2znwDO.png
data Status =
  Status {
    _version :: String
  , _build :: String
  , _hardwareBuild :: String
  , _devices :: Int
  , _connectedUsers :: Int
  , _uatMessagesLastMinute :: Int
  , _uatMessagesMax :: Int
  , _esMessagesLastMinute :: Int
  , _esMessagesMax :: Int
  , _gpsSatellitesLocked :: Int
  , _gpsSatellitesSeen :: Int
  , _gpsSatellitesTracked :: Int
  , _gpsConnected :: Bool
  , _gpsSolution :: GpsSolution
  , _ry835ai_connected :: Bool
  , _uptime :: Int64
  , _clock :: UTCTime
  , _uptimeClock :: UTCTime
  , _cpuTemp :: Float
  , _networkDataMessagesSent :: Int64
  , _networkDataMessagesSentNonqueueable :: Int64
  , _networkDataBytesSent :: Int64
  , _networkDataBytesSentNonqueueable :: Int64
  , _networkDataMessagesSentLastSec :: Int64
  , _networkDataMessagesSentNonqueueableLastSec :: Int64
  , _networkDataBytesSentLastSec :: Int64
  , _networkDataBytesSentNonqueueableLastSec :: Int64
  , _errors :: [String]
  } deriving (Eq, Ord, Show)

makeClassy ''Status

-- |
--
-- >>> decode "{\"Version\":\"v0.8r2\",\"Build\":\"db130aab76e9acde26b95c14014ced8fadbfeb80\",\"HardwareBuild\":\"\",\"Devices\":2,\"Connected_Users\":3,\"UAT_messages_last_minute\":0,\"UAT_messages_max\":0,\"ES_messages_last_minute\":68,\"ES_messages_max\":1295,\"GPS_satellites_locked\":10,\"GPS_satellites_seen\":12,\"GPS_satellites_tracked\":13,\"GPS_connected\":true,\"GPS_solution\":\"3D GPS\",\"RY835AI_connected\":false,\"Uptime\":12718050,\"Clock\":\"2016-06-07T04:41:55.70631916Z\",\"UptimeClock\":\"0001-01-01T03:31:58.05Z\",\"CPUTemp\":44.546,\"NetworkDataMessagesSent\":0,\"NetworkDataMessagesSentNonqueueable\":0,\"NetworkDataBytesSent\":0,\"NetworkDataBytesSentNonqueueable\":0,\"NetworkDataMessagesSentLastSec\":0,\"NetworkDataMessagesSentNonqueueableLastSec\":0,\"NetworkDataBytesSentLastSec\":0,\"NetworkDataBytesSentNonqueueableLastSec\":0,\"Errors\":[]}" :: Maybe Status
-- Just (Status {_version = "v0.8r2", _build = "db130aab76e9acde26b95c14014ced8fadbfeb80", _hardwareBuild = "", _devices = 2, _connectedUsers = 3, _uatMessagesLastMinute = 0, _uatMessagesMax = 0, _esMessagesLastMinute = 68, _esMessagesMax = 1295, _gpsSatellitesLocked = 10, _gpsSatellitesSeen = 12, _gpsSatellitesTracked = 13, _gpsConnected = True, _gpsSolution = ThreeDGPS, _ry835ai_connected = False, _uptime = 12718050, _clock = 2016-06-07 04:41:55.70631916 UTC, _uptimeClock = 0001-01-01 03:31:58.05 UTC, _cpuTemp = 44.546, _networkDataMessagesSent = 0, _networkDataMessagesSentNonqueueable = 0, _networkDataBytesSent = 0, _networkDataBytesSentNonqueueable = 0, _networkDataMessagesSentLastSec = 0, _networkDataMessagesSentNonqueueableLastSec = 0, _networkDataBytesSentLastSec = 0, _networkDataBytesSentNonqueueableLastSec = 0, _errors = []})
instance FromJSON Status where
  parseJSON =
    withObject "Status" (\x ->
      Status <$>
        x .: "Version" <*>
        x .: "Build" <*>
        x .: "HardwareBuild" <*>
        x .: "Devices" <*>
        x .: "Connected_Users" <*>
        x .: "UAT_messages_last_minute" <*>
        x .: "UAT_messages_max" <*>
        x .: "ES_messages_last_minute" <*>
        x .: "ES_messages_max" <*>
        x .: "GPS_satellites_locked" <*>
        x .: "GPS_satellites_seen" <*>
        x .: "GPS_satellites_tracked" <*>
        x .: "GPS_connected" <*>
        x .: "GPS_solution" <*>
        x .: "RY835AI_connected" <*>
        x .: "Uptime" <*>
        x .: "Clock" <*>
        x .: "UptimeClock" <*>
        x .: "CPUTemp" <*>
        x .: "NetworkDataMessagesSent" <*>
        x .: "NetworkDataMessagesSentNonqueueable" <*>
        x .: "NetworkDataBytesSent" <*>
        x .: "NetworkDataBytesSentNonqueueable" <*>
        x .: "NetworkDataMessagesSentLastSec" <*>
        x .: "NetworkDataMessagesSentNonqueueableLastSec" <*>
        x .: "NetworkDataBytesSentLastSec" <*>
        x .: "NetworkDataBytesSentNonqueueableLastSec" <*>
        x .: "Errors")

-- |
--
-- >>> encode (Status "v0.8r2" "db130aab76e9acde26b95c14014ced8fadbfeb80" "" 2 3 0 0 68 1295 10 12 13 True ThreeDGPS False 12718050 (UTCTime (fromGregorian 1 1 1) 23) (UTCTime (fromGregorian 1 1 1) 23) 44.546 0 0 0 0 0 0 0 0 [])
-- "{\"Connected_Users\":3,\"NetworkDataMessagesSentLastSec\":0,\"Clock\":\"0001-01-01T00:00:23Z\",\"UptimeClock\":\"0001-01-01T00:00:23Z\",\"Uptime\":12718050,\"Build\":\"db130aab76e9acde26b95c14014ced8fadbfeb80\",\"NetworkDataMessagesSentNonqueueable\":0,\"NetworkDataMessagesSentNonqueueableLastSec\":0,\"GPS_satellites_seen\":12,\"GPS_connected\":true,\"NetworkDataBytesSentLastSec\":0,\"UAT_messages_max\":0,\"NetworkDataBytesSentNonqueueable\":0,\"NetworkDataMessagesSent\":0,\"CPUTemp\":44.546,\"Version\":\"v0.8r2\",\"GPS_satellites_tracked\":13,\"GPS_solution\":\"3D GPS\",\"ES_messages_max\":1295,\"ES_messages_last_minute\":68,\"RY835AI_connected\":false,\"HardwareBuild\":\"\",\"NetworkDataBytesSentNonqueueableLastSec\":0,\"NetworkDataBytesSent\":0,\"Devices\":2,\"Errors\":[],\"UAT_messages_last_minute\":0,\"GPS_satellites_locked\":10}"
instance ToJSON Status where
  toJSON (Status version_ build_ hardwareBuild_ devices_ connectedUsers_ uatMessagesLastMinute_ uatMessagesMax_ esMessagesLastMinute_ esMessagesMax_ gpsSatellitesLocked_ gpsSatellitesSeen_ gpsSatellitesTracked_ gpsConnected_ gpsSolution_ ry835ai_connected_ uptime_ clock_ uptimeClock_ cpuTemp_ networkDataMessagesSent_ networkDataMessagesSentNonqueueable_ networkDataBytesSent_ networkDataBytesSentNonqueueable_ networkDataMessagesSentLastSec_ networkDataMessagesSentNonqueueableLastSec_ networkDataBytesSentLastSec_ networkDataBytesSentNonqueueableLastSec_ errors_) =
    object [
      "Version" .= version_
    , "Build" .= build_
    , "HardwareBuild" .= hardwareBuild_
    , "Devices" .= devices_
    , "Connected_Users" .= connectedUsers_
    , "UAT_messages_last_minute" .= uatMessagesLastMinute_
    , "UAT_messages_max" .= uatMessagesMax_
    , "ES_messages_last_minute" .= esMessagesLastMinute_
    , "ES_messages_max" .= esMessagesMax_
    , "GPS_satellites_locked" .= gpsSatellitesLocked_
    , "GPS_satellites_seen" .= gpsSatellitesSeen_
    , "GPS_satellites_tracked" .= gpsSatellitesTracked_
    , "GPS_connected" .= gpsConnected_
    , "GPS_solution" .= gpsSolution_
    , "RY835AI_connected" .= ry835ai_connected_
    , "Uptime" .= uptime_
    , "Clock" .= clock_
    , "UptimeClock" .= uptimeClock_
    , "CPUTemp" .= cpuTemp_
    , "NetworkDataMessagesSent" .= networkDataMessagesSent_
    , "NetworkDataMessagesSentNonqueueable" .= networkDataMessagesSentNonqueueable_
    , "NetworkDataBytesSent" .= networkDataBytesSent_
    , "NetworkDataBytesSentNonqueueable" .= networkDataBytesSentNonqueueable_
    , "NetworkDataMessagesSentLastSec" .= networkDataMessagesSentLastSec_
    , "NetworkDataMessagesSentNonqueueableLastSec" .= networkDataMessagesSentNonqueueableLastSec_
    , "NetworkDataBytesSentLastSec" .= networkDataBytesSentLastSec_
    , "NetworkDataBytesSentNonqueueableLastSec" .= networkDataBytesSentNonqueueableLastSec_
    , "Errors" .= errors_
    ]

instance HasUTCTimes Status where
  utcTimes f (Status version_ build_ hardwareBuild_ devices_ connectedUsers_ uatMessagesLastMinute_ uatMessagesMax_ esMessagesLastMinute_ esMessagesMax_ gpsSatellitesLocked_ gpsSatellitesSeen_ gpsSatellitesTracked_ gpsConnected_ gpsSolution_ ry835aiconnected_ uptime_ clock_ uptimeClock_ cpuTemp_ networkDataMessagesSent_ networkDataMessagesSentNonqueueable_ networkDataBytesSent_ networkDataBytesSentNonqueueable_ networkDataMessagesSentLastSec_ networkDataMessagesSentNonqueueableLastSec_ networkDataBytesSentLastSec_ networkDataBytesSentNonqueueableLastSec_ errors_) =
      (\clock__ uptimeClock__ ->
        Status version_ build_ hardwareBuild_ devices_ connectedUsers_ uatMessagesLastMinute_ uatMessagesMax_ esMessagesLastMinute_ esMessagesMax_ gpsSatellitesLocked_ gpsSatellitesSeen_ gpsSatellitesTracked_ gpsConnected_ gpsSolution_ ry835aiconnected_ uptime_ clock__ uptimeClock__ cpuTemp_ networkDataMessagesSent_ networkDataMessagesSentNonqueueable_ networkDataBytesSent_ networkDataBytesSentNonqueueable_ networkDataMessagesSentLastSec_ networkDataMessagesSentNonqueueableLastSec_ networkDataBytesSentLastSec_ networkDataBytesSentNonqueueableLastSec_ errors_) <$>
      f clock_ <*>
      f uptimeClock_