-- |
-- Module      : Net.DNSBase.Internal.Peer
-- Description : TBD
-- Copyright   : (c) Viktor Dukhovni, 2026
-- License     : BSD-3-Clause
-- Maintainer  : ietf-dane@dukhovni.org
-- Stability   : unstable
{-# LANGUAGE RecordWildCards #-}

module Net.DNSBase.Internal.Peer
    ( MessageSource(..)
    , DnsXprt ( DnsOverUDP
              , DnsOverTCP
              , DnsOverTLS
              , DnsOverQUIC
              )
    ) where
import Net.DNSBase.Internal.Present
import Net.DNSBase.Internal.Util

-- | Transport between DNS client and server
newtype DnsXprt = DnsXprt Word8
    deriving newtype (DnsXprt -> DnsXprt -> Bool
(DnsXprt -> DnsXprt -> Bool)
-> (DnsXprt -> DnsXprt -> Bool) -> Eq DnsXprt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DnsXprt -> DnsXprt -> Bool
== :: DnsXprt -> DnsXprt -> Bool
$c/= :: DnsXprt -> DnsXprt -> Bool
/= :: DnsXprt -> DnsXprt -> Bool
Eq, Eq DnsXprt
Eq DnsXprt =>
(DnsXprt -> DnsXprt -> Ordering)
-> (DnsXprt -> DnsXprt -> Bool)
-> (DnsXprt -> DnsXprt -> Bool)
-> (DnsXprt -> DnsXprt -> Bool)
-> (DnsXprt -> DnsXprt -> Bool)
-> (DnsXprt -> DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt -> DnsXprt)
-> Ord DnsXprt
DnsXprt -> DnsXprt -> Bool
DnsXprt -> DnsXprt -> Ordering
DnsXprt -> DnsXprt -> DnsXprt
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
$ccompare :: DnsXprt -> DnsXprt -> Ordering
compare :: DnsXprt -> DnsXprt -> Ordering
$c< :: DnsXprt -> DnsXprt -> Bool
< :: DnsXprt -> DnsXprt -> Bool
$c<= :: DnsXprt -> DnsXprt -> Bool
<= :: DnsXprt -> DnsXprt -> Bool
$c> :: DnsXprt -> DnsXprt -> Bool
> :: DnsXprt -> DnsXprt -> Bool
$c>= :: DnsXprt -> DnsXprt -> Bool
>= :: DnsXprt -> DnsXprt -> Bool
$cmax :: DnsXprt -> DnsXprt -> DnsXprt
max :: DnsXprt -> DnsXprt -> DnsXprt
$cmin :: DnsXprt -> DnsXprt -> DnsXprt
min :: DnsXprt -> DnsXprt -> DnsXprt
Ord, Int -> DnsXprt
DnsXprt -> Int
DnsXprt -> [DnsXprt]
DnsXprt -> DnsXprt
DnsXprt -> DnsXprt -> [DnsXprt]
DnsXprt -> DnsXprt -> DnsXprt -> [DnsXprt]
(DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt)
-> (Int -> DnsXprt)
-> (DnsXprt -> Int)
-> (DnsXprt -> [DnsXprt])
-> (DnsXprt -> DnsXprt -> [DnsXprt])
-> (DnsXprt -> DnsXprt -> [DnsXprt])
-> (DnsXprt -> DnsXprt -> DnsXprt -> [DnsXprt])
-> Enum DnsXprt
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: DnsXprt -> DnsXprt
succ :: DnsXprt -> DnsXprt
$cpred :: DnsXprt -> DnsXprt
pred :: DnsXprt -> DnsXprt
$ctoEnum :: Int -> DnsXprt
toEnum :: Int -> DnsXprt
$cfromEnum :: DnsXprt -> Int
fromEnum :: DnsXprt -> Int
$cenumFrom :: DnsXprt -> [DnsXprt]
enumFrom :: DnsXprt -> [DnsXprt]
$cenumFromThen :: DnsXprt -> DnsXprt -> [DnsXprt]
enumFromThen :: DnsXprt -> DnsXprt -> [DnsXprt]
$cenumFromTo :: DnsXprt -> DnsXprt -> [DnsXprt]
enumFromTo :: DnsXprt -> DnsXprt -> [DnsXprt]
$cenumFromThenTo :: DnsXprt -> DnsXprt -> DnsXprt -> [DnsXprt]
enumFromThenTo :: DnsXprt -> DnsXprt -> DnsXprt -> [DnsXprt]
Enum, DnsXprt
DnsXprt -> DnsXprt -> Bounded DnsXprt
forall a. a -> a -> Bounded a
$cminBound :: DnsXprt
minBound :: DnsXprt
$cmaxBound :: DnsXprt
maxBound :: DnsXprt
Bounded, Integer -> DnsXprt
DnsXprt -> DnsXprt
DnsXprt -> DnsXprt -> DnsXprt
(DnsXprt -> DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt)
-> (Integer -> DnsXprt)
-> Num DnsXprt
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: DnsXprt -> DnsXprt -> DnsXprt
+ :: DnsXprt -> DnsXprt -> DnsXprt
$c- :: DnsXprt -> DnsXprt -> DnsXprt
- :: DnsXprt -> DnsXprt -> DnsXprt
$c* :: DnsXprt -> DnsXprt -> DnsXprt
* :: DnsXprt -> DnsXprt -> DnsXprt
$cnegate :: DnsXprt -> DnsXprt
negate :: DnsXprt -> DnsXprt
$cabs :: DnsXprt -> DnsXprt
abs :: DnsXprt -> DnsXprt
$csignum :: DnsXprt -> DnsXprt
signum :: DnsXprt -> DnsXprt
$cfromInteger :: Integer -> DnsXprt
fromInteger :: Integer -> DnsXprt
Num, Num DnsXprt
Ord DnsXprt
(Num DnsXprt, Ord DnsXprt) => (DnsXprt -> Rational) -> Real DnsXprt
DnsXprt -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: DnsXprt -> Rational
toRational :: DnsXprt -> Rational
Real, Enum DnsXprt
Real DnsXprt
(Real DnsXprt, Enum DnsXprt) =>
(DnsXprt -> DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt -> DnsXprt)
-> (DnsXprt -> DnsXprt -> (DnsXprt, DnsXprt))
-> (DnsXprt -> DnsXprt -> (DnsXprt, DnsXprt))
-> (DnsXprt -> Integer)
-> Integral DnsXprt
DnsXprt -> Integer
DnsXprt -> DnsXprt -> (DnsXprt, DnsXprt)
DnsXprt -> DnsXprt -> DnsXprt
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: DnsXprt -> DnsXprt -> DnsXprt
quot :: DnsXprt -> DnsXprt -> DnsXprt
$crem :: DnsXprt -> DnsXprt -> DnsXprt
rem :: DnsXprt -> DnsXprt -> DnsXprt
$cdiv :: DnsXprt -> DnsXprt -> DnsXprt
div :: DnsXprt -> DnsXprt -> DnsXprt
$cmod :: DnsXprt -> DnsXprt -> DnsXprt
mod :: DnsXprt -> DnsXprt -> DnsXprt
$cquotRem :: DnsXprt -> DnsXprt -> (DnsXprt, DnsXprt)
quotRem :: DnsXprt -> DnsXprt -> (DnsXprt, DnsXprt)
$cdivMod :: DnsXprt -> DnsXprt -> (DnsXprt, DnsXprt)
divMod :: DnsXprt -> DnsXprt -> (DnsXprt, DnsXprt)
$ctoInteger :: DnsXprt -> Integer
toInteger :: DnsXprt -> Integer
Integral)

instance Presentable DnsXprt where
    present :: DnsXprt -> Builder -> Builder
present DnsXprt
DnsOverUDP  = forall a. Presentable a => a -> Builder -> Builder
present @String String
"UDP"
    present DnsXprt
DnsOverTCP  = forall a. Presentable a => a -> Builder -> Builder
present @String String
"TCP"
    present DnsXprt
DnsOverTLS  = forall a. Presentable a => a -> Builder -> Builder
present @String String
"DoT"
    present DnsXprt
DnsOverQUIC = forall a. Presentable a => a -> Builder -> Builder
present @String String
"DoQ"
    present DnsXprt
t           = forall a. Presentable a => a -> Builder -> Builder
present @String String
"Xprt" (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Presentable a => a -> Builder -> Builder
present @Word8 (DnsXprt -> Word8
forall a b. Coercible a b => a -> b
coerce DnsXprt
t)

pattern DnsOverUDP  :: DnsXprt; pattern $mDnsOverUDP :: forall {r}. DnsXprt -> ((# #) -> r) -> ((# #) -> r) -> r
$bDnsOverUDP :: DnsXprt
DnsOverUDP  = DnsXprt 0
pattern DnsOverTCP  :: DnsXprt; pattern $mDnsOverTCP :: forall {r}. DnsXprt -> ((# #) -> r) -> ((# #) -> r) -> r
$bDnsOverTCP :: DnsXprt
DnsOverTCP  = DnsXprt 1
pattern DnsOverTLS  :: DnsXprt; pattern $mDnsOverTLS :: forall {r}. DnsXprt -> ((# #) -> r) -> ((# #) -> r) -> r
$bDnsOverTLS :: DnsXprt
DnsOverTLS  = DnsXprt 2
pattern DnsOverQUIC :: DnsXprt; pattern $mDnsOverQUIC :: forall {r}. DnsXprt -> ((# #) -> r) -> ((# #) -> r) -> r
$bDnsOverQUIC :: DnsXprt
DnsOverQUIC = DnsXprt 3

-- | DNS client or server peer endpoint.
data MessageSource = MessageSource
    { MessageSource -> DnsXprt
dnsPeerXprt :: DnsXprt
    , MessageSource -> Maybe String
dnsPeerName :: Maybe String
    , MessageSource -> IP
dnsPeerAddr :: IP
    , MessageSource -> Word16
dnsPeerPort :: Word16
    } deriving (MessageSource -> MessageSource -> Bool
(MessageSource -> MessageSource -> Bool)
-> (MessageSource -> MessageSource -> Bool) -> Eq MessageSource
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MessageSource -> MessageSource -> Bool
== :: MessageSource -> MessageSource -> Bool
$c/= :: MessageSource -> MessageSource -> Bool
/= :: MessageSource -> MessageSource -> Bool
Eq)

instance Presentable MessageSource where
    present :: MessageSource -> Builder -> Builder
present MessageSource {Maybe String
Word16
IP
DnsXprt
dnsPeerXprt :: MessageSource -> DnsXprt
dnsPeerName :: MessageSource -> Maybe String
dnsPeerAddr :: MessageSource -> IP
dnsPeerPort :: MessageSource -> Word16
dnsPeerXprt :: DnsXprt
dnsPeerName :: Maybe String
dnsPeerAddr :: IP
dnsPeerPort :: Word16
..} =
        DnsXprt -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present DnsXprt
dnsPeerXprt (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present Char
'@'
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Builder -> Builder)
-> (String -> Builder -> Builder)
-> Maybe String
-> Builder
-> Builder
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Builder -> Builder
forall a. a -> a
id String -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present Maybe String
dnsPeerName
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> IP -> Builder -> Builder
forall a. Presentable a => Char -> a -> Builder -> Builder
presentCharSep Char
'[' IP
dnsPeerAddr (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present Char
']'
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Word16 -> Builder -> Builder
forall a. Presentable a => Char -> a -> Builder -> Builder
presentCharSep Char
':' Word16
dnsPeerPort