{-# OPTIONS_GHC -Wno-orphans #-} -- :/
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

{-|
Module:      SignalDBus.Types
Description: Types used by this package
Copyright:   (c) Lia Lenckowski, 2022
License:     AGPL
Maintainer:  lialenck@protonmail.com
Stability:   experimental
Portability: GNU/Linux, MacOS

This module contains types used by this package. Please import SignalDBus instead.
-}

module SignalDBus.Types (
    SignalConn(..),
    Timestamp,
    Device(..),
    Group(..),
    ReceivedMessage(..),

    toUTCTime,
    fromUTCTime,
) where

import Data.Int (Int64)
import Data.Time (UTCTime)
import Data.Time.Clock.POSIX (posixSecondsToUTCTime, utcTimeToPOSIXSeconds)
import DBus.Client (Client)
import DBus.Internal.Types
import Text.Read (readPrec)

-- |Opaque connection object, aquired by 'SignalDBus.withConn' or
-- 'SignalDBus.withConnNum'
data SignalConn = SignalConn !ObjectPath !Client

-- |Timestamp, represented as an ms-precision unix timestamp
newtype Timestamp = Timestamp Int64 deriving (Int -> Timestamp -> ShowS
[Timestamp] -> ShowS
Timestamp -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Timestamp] -> ShowS
$cshowList :: [Timestamp] -> ShowS
show :: Timestamp -> String
$cshow :: Timestamp -> String
showsPrec :: Int -> Timestamp -> ShowS
$cshowsPrec :: Int -> Timestamp -> ShowS
Show, ReadPrec [Timestamp]
ReadPrec Timestamp
Int -> ReadS Timestamp
ReadS [Timestamp]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Timestamp]
$creadListPrec :: ReadPrec [Timestamp]
readPrec :: ReadPrec Timestamp
$creadPrec :: ReadPrec Timestamp
readList :: ReadS [Timestamp]
$creadList :: ReadS [Timestamp]
readsPrec :: Int -> ReadS Timestamp
$creadsPrec :: Int -> ReadS Timestamp
Read, Timestamp -> Timestamp -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Timestamp -> Timestamp -> Bool
$c/= :: Timestamp -> Timestamp -> Bool
== :: Timestamp -> Timestamp -> Bool
$c== :: Timestamp -> Timestamp -> Bool
Eq, Eq Timestamp
Timestamp -> Timestamp -> Bool
Timestamp -> Timestamp -> Ordering
Timestamp -> Timestamp -> Timestamp
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Timestamp -> Timestamp -> Timestamp
$cmin :: Timestamp -> Timestamp -> Timestamp
max :: Timestamp -> Timestamp -> Timestamp
$cmax :: Timestamp -> Timestamp -> Timestamp
>= :: Timestamp -> Timestamp -> Bool
$c>= :: Timestamp -> Timestamp -> Bool
> :: Timestamp -> Timestamp -> Bool
$c> :: Timestamp -> Timestamp -> Bool
<= :: Timestamp -> Timestamp -> Bool
$c<= :: Timestamp -> Timestamp -> Bool
< :: Timestamp -> Timestamp -> Bool
$c< :: Timestamp -> Timestamp -> Bool
compare :: Timestamp -> Timestamp -> Ordering
$ccompare :: Timestamp -> Timestamp -> Ordering
Ord, Variant -> Maybe Timestamp
Timestamp -> Variant
forall a. (a -> Variant) -> (Variant -> Maybe a) -> IsVariant a
fromVariant :: Variant -> Maybe Timestamp
$cfromVariant :: Variant -> Maybe Timestamp
toVariant :: Timestamp -> Variant
$ctoVariant :: Timestamp -> Variant
IsVariant, IsVariant Timestamp
Proxy Timestamp -> Type
Value -> Maybe Timestamp
Timestamp -> Value
forall a.
IsVariant a
-> (Proxy a -> Type)
-> (a -> Value)
-> (Value -> Maybe a)
-> IsValue a
fromValue :: Value -> Maybe Timestamp
$cfromValue :: Value -> Maybe Timestamp
toValue :: Timestamp -> Value
$ctoValue :: Timestamp -> Value
typeOf_ :: Proxy Timestamp -> Type
$ctypeOf_ :: Proxy Timestamp -> Type
IsValue)
-- |Conversion to 'UTCTime'. This retains precision, so converting back-and-forth
-- is unproblematic.
toUTCTime :: Timestamp -> UTCTime
toUTCTime :: Timestamp -> UTCTime
toUTCTime (Timestamp Int64
ts) = POSIXTime -> UTCTime
posixSecondsToUTCTime (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
ts forall a. Num a => a -> a -> a
* POSIXTime
0.001)
-- |Conversion from 'UTCTime'. This retains precision, so converting back-and-forth
-- is unproblematic.
fromUTCTime :: UTCTime -> Timestamp
fromUTCTime :: UTCTime -> Timestamp
fromUTCTime UTCTime
t = Int64 -> Timestamp
Timestamp forall a b. (a -> b) -> a -> b
$ forall a b. (RealFrac a, Integral b) => a -> b
floor forall a b. (a -> b) -> a -> b
$ UTCTime -> POSIXTime
utcTimeToPOSIXSeconds UTCTime
t forall a. Num a => a -> a -> a
* POSIXTime
1000

-- |Opaque object representing a linked device
newtype Device = Device Int64 deriving (Int -> Device -> ShowS
[Device] -> ShowS
Device -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Device] -> ShowS
$cshowList :: [Device] -> ShowS
show :: Device -> String
$cshow :: Device -> String
showsPrec :: Int -> Device -> ShowS
$cshowsPrec :: Int -> Device -> ShowS
Show, ReadPrec [Device]
ReadPrec Device
Int -> ReadS Device
ReadS [Device]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Device]
$creadListPrec :: ReadPrec [Device]
readPrec :: ReadPrec Device
$creadPrec :: ReadPrec Device
readList :: ReadS [Device]
$creadList :: ReadS [Device]
readsPrec :: Int -> ReadS Device
$creadsPrec :: Int -> ReadS Device
Read, Device -> Device -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Device -> Device -> Bool
$c/= :: Device -> Device -> Bool
== :: Device -> Device -> Bool
$c== :: Device -> Device -> Bool
Eq, Variant -> Maybe Device
Device -> Variant
forall a. (a -> Variant) -> (Variant -> Maybe a) -> IsVariant a
fromVariant :: Variant -> Maybe Device
$cfromVariant :: Variant -> Maybe Device
toVariant :: Device -> Variant
$ctoVariant :: Device -> Variant
IsVariant, IsVariant Device
Proxy Device -> Type
Value -> Maybe Device
Device -> Value
forall a.
IsVariant a
-> (Proxy a -> Type)
-> (a -> Value)
-> (Value -> Maybe a)
-> IsValue a
fromValue :: Value -> Maybe Device
$cfromValue :: Value -> Maybe Device
toValue :: Device -> Value
$ctoValue :: Device -> Value
typeOf_ :: Proxy Device -> Type
$ctypeOf_ :: Proxy Device -> Type
IsValue)

instance Read ObjectPath where -- :/
    readPrec :: ReadPrec ObjectPath
readPrec = String -> ObjectPath
ObjectPath forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Read a => ReadPrec a
readPrec

-- |Opaque Group object, aquired by 'SignalDBus.listGroups' or 'SignalDBus.getGroup'
newtype Group = Group ObjectPath deriving (Int -> Group -> ShowS
[Group] -> ShowS
Group -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Group] -> ShowS
$cshowList :: [Group] -> ShowS
show :: Group -> String
$cshow :: Group -> String
showsPrec :: Int -> Group -> ShowS
$cshowsPrec :: Int -> Group -> ShowS
Show, ReadPrec [Group]
ReadPrec Group
Int -> ReadS Group
ReadS [Group]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Group]
$creadListPrec :: ReadPrec [Group]
readPrec :: ReadPrec Group
$creadPrec :: ReadPrec Group
readList :: ReadS [Group]
$creadList :: ReadS [Group]
readsPrec :: Int -> ReadS Group
$creadsPrec :: Int -> ReadS Group
Read, Group -> Group -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Group -> Group -> Bool
$c/= :: Group -> Group -> Bool
== :: Group -> Group -> Bool
$c== :: Group -> Group -> Bool
Eq, Eq Group
Group -> Group -> Bool
Group -> Group -> Ordering
Group -> Group -> Group
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Group -> Group -> Group
$cmin :: Group -> Group -> Group
max :: Group -> Group -> Group
$cmax :: Group -> Group -> Group
>= :: Group -> Group -> Bool
$c>= :: Group -> Group -> Bool
> :: Group -> Group -> Bool
$c> :: Group -> Group -> Bool
<= :: Group -> Group -> Bool
$c<= :: Group -> Group -> Bool
< :: Group -> Group -> Bool
$c< :: Group -> Group -> Bool
compare :: Group -> Group -> Ordering
$ccompare :: Group -> Group -> Ordering
Ord, Variant -> Maybe Group
Group -> Variant
forall a. (a -> Variant) -> (Variant -> Maybe a) -> IsVariant a
fromVariant :: Variant -> Maybe Group
$cfromVariant :: Variant -> Maybe Group
toVariant :: Group -> Variant
$ctoVariant :: Group -> Variant
IsVariant, IsVariant Group
Proxy Group -> Type
Value -> Maybe Group
Group -> Value
forall a.
IsVariant a
-> (Proxy a -> Type)
-> (a -> Value)
-> (Value -> Maybe a)
-> IsValue a
fromValue :: Value -> Maybe Group
$cfromValue :: Value -> Maybe Group
toValue :: Group -> Value
$ctoValue :: Group -> Value
typeOf_ :: Proxy Group -> Type
$ctypeOf_ :: Proxy Group -> Type
IsValue)

-- |Received message
data ReceivedMessage =
    SyncMessage       -- ^ Message sent by a linked device to someone else
        Timestamp     -- ^ When this message was sent
        String        -- ^ Message sender (TODO: always yourself?)
        (Maybe Group) -- ^ If sent in a group, corresponding group object
        String        -- ^ Message text
        [String]      -- ^ Paths to stored attachments

  | Receipt       -- ^ Read receipt sent by someone else in response to one of your messages
        Timestamp -- ^ Which message was read
        String    -- ^ Phone number of the receipt sender

  | Message           -- ^ Message sent to you by someone else
        Timestamp     -- ^ When this message was sent
        String        -- ^ Message sender
        (Maybe Group) -- ^ If sent in a group, corresponding group object
        String        -- ^ Message text
        [String]      -- ^ Paths to stored attachments

    deriving (Int -> ReceivedMessage -> ShowS
[ReceivedMessage] -> ShowS
ReceivedMessage -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ReceivedMessage] -> ShowS
$cshowList :: [ReceivedMessage] -> ShowS
show :: ReceivedMessage -> String
$cshow :: ReceivedMessage -> String
showsPrec :: Int -> ReceivedMessage -> ShowS
$cshowsPrec :: Int -> ReceivedMessage -> ShowS
Show, ReadPrec [ReceivedMessage]
ReadPrec ReceivedMessage
Int -> ReadS ReceivedMessage
ReadS [ReceivedMessage]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ReceivedMessage]
$creadListPrec :: ReadPrec [ReceivedMessage]
readPrec :: ReadPrec ReceivedMessage
$creadPrec :: ReadPrec ReceivedMessage
readList :: ReadS [ReceivedMessage]
$creadList :: ReadS [ReceivedMessage]
readsPrec :: Int -> ReadS ReceivedMessage
$creadsPrec :: Int -> ReadS ReceivedMessage
Read, ReceivedMessage -> ReceivedMessage -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReceivedMessage -> ReceivedMessage -> Bool
$c/= :: ReceivedMessage -> ReceivedMessage -> Bool
== :: ReceivedMessage -> ReceivedMessage -> Bool
$c== :: ReceivedMessage -> ReceivedMessage -> Bool
Eq, Eq ReceivedMessage
ReceivedMessage -> ReceivedMessage -> Bool
ReceivedMessage -> ReceivedMessage -> Ordering
ReceivedMessage -> ReceivedMessage -> ReceivedMessage
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ReceivedMessage -> ReceivedMessage -> ReceivedMessage
$cmin :: ReceivedMessage -> ReceivedMessage -> ReceivedMessage
max :: ReceivedMessage -> ReceivedMessage -> ReceivedMessage
$cmax :: ReceivedMessage -> ReceivedMessage -> ReceivedMessage
>= :: ReceivedMessage -> ReceivedMessage -> Bool
$c>= :: ReceivedMessage -> ReceivedMessage -> Bool
> :: ReceivedMessage -> ReceivedMessage -> Bool
$c> :: ReceivedMessage -> ReceivedMessage -> Bool
<= :: ReceivedMessage -> ReceivedMessage -> Bool
$c<= :: ReceivedMessage -> ReceivedMessage -> Bool
< :: ReceivedMessage -> ReceivedMessage -> Bool
$c< :: ReceivedMessage -> ReceivedMessage -> Bool
compare :: ReceivedMessage -> ReceivedMessage -> Ordering
$ccompare :: ReceivedMessage -> ReceivedMessage -> Ordering
Ord)