    {-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE FlexibleInstances #-}

    module Propellor.Types.Dns where

    import Propellor.Types.OS (HostName)
    import Propellor.Types.Empty
    import Propellor.Types.Info
    import Propellor.Types.ConfigurableValue
    import Utility.Split

    import Data.Word
    import qualified Data.Map as M
    import qualified Data.Set as S
    import qualified Data.Semigroup as Sem
    import Data.List
    import Data.Monoid
    import Prelude

    type Domain = String

    data IPAddr = IPv4 String | IPv6 String
    	deriving (ReadPrec [IPAddr]
    ReadPrec IPAddr
    Int -> ReadS IPAddr
    ReadS [IPAddr]
    (Int -> ReadS IPAddr)
    -> ReadS [IPAddr]
    -> ReadPrec IPAddr
    -> ReadPrec [IPAddr]
    -> Read IPAddr
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [IPAddr]
    $creadListPrec :: ReadPrec [IPAddr]
    readPrec :: ReadPrec IPAddr
    $creadPrec :: ReadPrec IPAddr
    readList :: ReadS [IPAddr]
    $creadList :: ReadS [IPAddr]
    readsPrec :: Int -> ReadS IPAddr
    $creadsPrec :: Int -> ReadS IPAddr
    Read, Int -> IPAddr -> ShowS
    [IPAddr] -> ShowS
    IPAddr -> String
    (Int -> IPAddr -> ShowS)
    -> (IPAddr -> String) -> ([IPAddr] -> ShowS) -> Show IPAddr
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [IPAddr] -> ShowS
    $cshowList :: [IPAddr] -> ShowS
    show :: IPAddr -> String
    $cshow :: IPAddr -> String
    showsPrec :: Int -> IPAddr -> ShowS
    $cshowsPrec :: Int -> IPAddr -> ShowS
    Show, IPAddr -> IPAddr -> Bool
    (IPAddr -> IPAddr -> Bool)
    -> (IPAddr -> IPAddr -> Bool) -> Eq IPAddr
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: IPAddr -> IPAddr -> Bool
    $c/= :: IPAddr -> IPAddr -> Bool
    == :: IPAddr -> IPAddr -> Bool
    $c== :: IPAddr -> IPAddr -> Bool
    Eq, Eq IPAddr
    Eq IPAddr =>
    (IPAddr -> IPAddr -> Ordering)
    -> (IPAddr -> IPAddr -> Bool)
    -> (IPAddr -> IPAddr -> Bool)
    -> (IPAddr -> IPAddr -> Bool)
    -> (IPAddr -> IPAddr -> Bool)
    -> (IPAddr -> IPAddr -> IPAddr)
    -> (IPAddr -> IPAddr -> IPAddr)
    -> Ord IPAddr
    IPAddr -> IPAddr -> Bool
    IPAddr -> IPAddr -> Ordering
    IPAddr -> IPAddr -> IPAddr
    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 :: IPAddr -> IPAddr -> IPAddr
    $cmin :: IPAddr -> IPAddr -> IPAddr
    max :: IPAddr -> IPAddr -> IPAddr
    $cmax :: IPAddr -> IPAddr -> IPAddr
    >= :: IPAddr -> IPAddr -> Bool
    $c>= :: IPAddr -> IPAddr -> Bool
    > :: IPAddr -> IPAddr -> Bool
    $c> :: IPAddr -> IPAddr -> Bool
    <= :: IPAddr -> IPAddr -> Bool
    $c<= :: IPAddr -> IPAddr -> Bool
    < :: IPAddr -> IPAddr -> Bool
    $c< :: IPAddr -> IPAddr -> Bool
    compare :: IPAddr -> IPAddr -> Ordering
    $ccompare :: IPAddr -> IPAddr -> Ordering
    $cp1Ord :: Eq IPAddr
    Ord)

    instance ConfigurableValue IPAddr where
    	val :: IPAddr -> String
    val (IPv4 addr :: String
    addr) = String
    addr
    	val (IPv6 addr :: String
    addr) = String
    addr

    newtype AliasesInfo = AliasesInfo (S.Set HostName)
    	deriving (Int -> AliasesInfo -> ShowS
    [AliasesInfo] -> ShowS
    AliasesInfo -> String
    (Int -> AliasesInfo -> ShowS)
    -> (AliasesInfo -> String)
    -> ([AliasesInfo] -> ShowS)
    -> Show AliasesInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [AliasesInfo] -> ShowS
    $cshowList :: [AliasesInfo] -> ShowS
    show :: AliasesInfo -> String
    $cshow :: AliasesInfo -> String
    showsPrec :: Int -> AliasesInfo -> ShowS
    $cshowsPrec :: Int -> AliasesInfo -> ShowS
    Show, AliasesInfo -> AliasesInfo -> Bool
    (AliasesInfo -> AliasesInfo -> Bool)
    -> (AliasesInfo -> AliasesInfo -> Bool) -> Eq AliasesInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: AliasesInfo -> AliasesInfo -> Bool
    $c/= :: AliasesInfo -> AliasesInfo -> Bool
    == :: AliasesInfo -> AliasesInfo -> Bool
    $c== :: AliasesInfo -> AliasesInfo -> Bool
    Eq, Eq AliasesInfo
    Eq AliasesInfo =>
    (AliasesInfo -> AliasesInfo -> Ordering)
    -> (AliasesInfo -> AliasesInfo -> Bool)
    -> (AliasesInfo -> AliasesInfo -> Bool)
    -> (AliasesInfo -> AliasesInfo -> Bool)
    -> (AliasesInfo -> AliasesInfo -> Bool)
    -> (AliasesInfo -> AliasesInfo -> AliasesInfo)
    -> (AliasesInfo -> AliasesInfo -> AliasesInfo)
    -> Ord AliasesInfo
    AliasesInfo -> AliasesInfo -> Bool
    AliasesInfo -> AliasesInfo -> Ordering
    AliasesInfo -> AliasesInfo -> AliasesInfo
    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 :: AliasesInfo -> AliasesInfo -> AliasesInfo
    $cmin :: AliasesInfo -> AliasesInfo -> AliasesInfo
    max :: AliasesInfo -> AliasesInfo -> AliasesInfo
    $cmax :: AliasesInfo -> AliasesInfo -> AliasesInfo
    >= :: AliasesInfo -> AliasesInfo -> Bool
    $c>= :: AliasesInfo -> AliasesInfo -> Bool
    > :: AliasesInfo -> AliasesInfo -> Bool
    $c> :: AliasesInfo -> AliasesInfo -> Bool
    <= :: AliasesInfo -> AliasesInfo -> Bool
    $c<= :: AliasesInfo -> AliasesInfo -> Bool
    < :: AliasesInfo -> AliasesInfo -> Bool
    $c< :: AliasesInfo -> AliasesInfo -> Bool
    compare :: AliasesInfo -> AliasesInfo -> Ordering
    $ccompare :: AliasesInfo -> AliasesInfo -> Ordering
    $cp1Ord :: Eq AliasesInfo
    Ord, b -> AliasesInfo -> AliasesInfo
    NonEmpty AliasesInfo -> AliasesInfo
    AliasesInfo -> AliasesInfo -> AliasesInfo
    (AliasesInfo -> AliasesInfo -> AliasesInfo)
    -> (NonEmpty AliasesInfo -> AliasesInfo)
    -> (forall b. Integral b => b -> AliasesInfo -> AliasesInfo)
    -> Semigroup AliasesInfo
    forall b. Integral b => b -> AliasesInfo -> AliasesInfo
    forall a.
    (a -> a -> a)
    -> (NonEmpty a -> a)
    -> (forall b. Integral b => b -> a -> a)
    -> Semigroup a
    stimes :: b -> AliasesInfo -> AliasesInfo
    $cstimes :: forall b. Integral b => b -> AliasesInfo -> AliasesInfo
    sconcat :: NonEmpty AliasesInfo -> AliasesInfo
    $csconcat :: NonEmpty AliasesInfo -> AliasesInfo
    <> :: AliasesInfo -> AliasesInfo -> AliasesInfo
    $c<> :: AliasesInfo -> AliasesInfo -> AliasesInfo
    Sem.Semigroup, Semigroup AliasesInfo
    AliasesInfo
    Semigroup AliasesInfo =>
    AliasesInfo
    -> (AliasesInfo -> AliasesInfo -> AliasesInfo)
    -> ([AliasesInfo] -> AliasesInfo)
    -> Monoid AliasesInfo
    [AliasesInfo] -> AliasesInfo
    AliasesInfo -> AliasesInfo -> AliasesInfo
    forall a.
    Semigroup a =>
    a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
    mconcat :: [AliasesInfo] -> AliasesInfo
    $cmconcat :: [AliasesInfo] -> AliasesInfo
    mappend :: AliasesInfo -> AliasesInfo -> AliasesInfo
    $cmappend :: AliasesInfo -> AliasesInfo -> AliasesInfo
    mempty :: AliasesInfo
    $cmempty :: AliasesInfo
    $cp1Monoid :: Semigroup AliasesInfo
    Monoid, Typeable)

    instance IsInfo AliasesInfo where
    	propagateInfo :: AliasesInfo -> PropagateInfo
    propagateInfo _ = Bool -> PropagateInfo
    PropagateInfo Bool
    False

    toAliasesInfo :: [HostName] -> AliasesInfo
    toAliasesInfo :: [String] -> AliasesInfo
    toAliasesInfo l :: [String]
    l = Set String -> AliasesInfo
    AliasesInfo ([String] -> Set String
    forall a. Ord a => [a] -> Set a
    S.fromList [String]
    l)

    fromAliasesInfo :: AliasesInfo -> [HostName]
    fromAliasesInfo :: AliasesInfo -> [String]
    fromAliasesInfo (AliasesInfo s :: Set String
    s) = Set String -> [String]
    forall a. Set a -> [a]
    S.toList Set String
    s

    -- | Use this for DNS Info that should propagate from a container to a
    -- host. For example, this can be used for CNAME to make aliases
    -- of the containers in the host be reflected in the DNS.
    newtype DnsInfoPropagated = DnsInfoPropagated
    	{ DnsInfoPropagated -> Set Record
    fromDnsInfoPropagated :: S.Set Record }
    	deriving (Int -> DnsInfoPropagated -> ShowS
    [DnsInfoPropagated] -> ShowS
    DnsInfoPropagated -> String
    (Int -> DnsInfoPropagated -> ShowS)
    -> (DnsInfoPropagated -> String)
    -> ([DnsInfoPropagated] -> ShowS)
    -> Show DnsInfoPropagated
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [DnsInfoPropagated] -> ShowS
    $cshowList :: [DnsInfoPropagated] -> ShowS
    show :: DnsInfoPropagated -> String
    $cshow :: DnsInfoPropagated -> String
    showsPrec :: Int -> DnsInfoPropagated -> ShowS
    $cshowsPrec :: Int -> DnsInfoPropagated -> ShowS
    Show, DnsInfoPropagated -> DnsInfoPropagated -> Bool
    (DnsInfoPropagated -> DnsInfoPropagated -> Bool)
    -> (DnsInfoPropagated -> DnsInfoPropagated -> Bool)
    -> Eq DnsInfoPropagated
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    $c/= :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    == :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    $c== :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    Eq, Eq DnsInfoPropagated
    Eq DnsInfoPropagated =>
    (DnsInfoPropagated -> DnsInfoPropagated -> Ordering)
    -> (DnsInfoPropagated -> DnsInfoPropagated -> Bool)
    -> (DnsInfoPropagated -> DnsInfoPropagated -> Bool)
    -> (DnsInfoPropagated -> DnsInfoPropagated -> Bool)
    -> (DnsInfoPropagated -> DnsInfoPropagated -> Bool)
    -> (DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated)
    -> (DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated)
    -> Ord DnsInfoPropagated
    DnsInfoPropagated -> DnsInfoPropagated -> Bool
    DnsInfoPropagated -> DnsInfoPropagated -> Ordering
    DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    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 :: DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    $cmin :: DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    max :: DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    $cmax :: DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    >= :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    $c>= :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    > :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    $c> :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    <= :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    $c<= :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    < :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    $c< :: DnsInfoPropagated -> DnsInfoPropagated -> Bool
    compare :: DnsInfoPropagated -> DnsInfoPropagated -> Ordering
    $ccompare :: DnsInfoPropagated -> DnsInfoPropagated -> Ordering
    $cp1Ord :: Eq DnsInfoPropagated
    Ord, b -> DnsInfoPropagated -> DnsInfoPropagated
    NonEmpty DnsInfoPropagated -> DnsInfoPropagated
    DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    (DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated)
    -> (NonEmpty DnsInfoPropagated -> DnsInfoPropagated)
    -> (forall b.
        Integral b =>
        b -> DnsInfoPropagated -> DnsInfoPropagated)
    -> Semigroup DnsInfoPropagated
    forall b. Integral b => b -> DnsInfoPropagated -> DnsInfoPropagated
    forall a.
    (a -> a -> a)
    -> (NonEmpty a -> a)
    -> (forall b. Integral b => b -> a -> a)
    -> Semigroup a
    stimes :: b -> DnsInfoPropagated -> DnsInfoPropagated
    $cstimes :: forall b. Integral b => b -> DnsInfoPropagated -> DnsInfoPropagated
    sconcat :: NonEmpty DnsInfoPropagated -> DnsInfoPropagated
    $csconcat :: NonEmpty DnsInfoPropagated -> DnsInfoPropagated
    <> :: DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    $c<> :: DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    Sem.Semigroup, Semigroup DnsInfoPropagated
    DnsInfoPropagated
    Semigroup DnsInfoPropagated =>
    DnsInfoPropagated
    -> (DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated)
    -> ([DnsInfoPropagated] -> DnsInfoPropagated)
    -> Monoid DnsInfoPropagated
    [DnsInfoPropagated] -> DnsInfoPropagated
    DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    forall a.
    Semigroup a =>
    a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
    mconcat :: [DnsInfoPropagated] -> DnsInfoPropagated
    $cmconcat :: [DnsInfoPropagated] -> DnsInfoPropagated
    mappend :: DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    $cmappend :: DnsInfoPropagated -> DnsInfoPropagated -> DnsInfoPropagated
    mempty :: DnsInfoPropagated
    $cmempty :: DnsInfoPropagated
    $cp1Monoid :: Semigroup DnsInfoPropagated
    Monoid, Typeable)

    toDnsInfoPropagated :: S.Set Record -> DnsInfoPropagated
    toDnsInfoPropagated :: Set Record -> DnsInfoPropagated
    toDnsInfoPropagated = Set Record -> DnsInfoPropagated
    DnsInfoPropagated

    instance IsInfo DnsInfoPropagated where
    	propagateInfo :: DnsInfoPropagated -> PropagateInfo
    propagateInfo _ = Bool -> PropagateInfo
    PropagateInfo Bool
    True

    -- | Use this for DNS Info that should not propagate from a container to a
    -- host. For example, an IP address of a container should not influence
    -- the host.
    newtype DnsInfoUnpropagated = DnsInfoUnpropagated
    	{ DnsInfoUnpropagated -> Set Record
    fromDnsInfoUnpropagated :: S.Set Record }
    	deriving (Int -> DnsInfoUnpropagated -> ShowS
    [DnsInfoUnpropagated] -> ShowS
    DnsInfoUnpropagated -> String
    (Int -> DnsInfoUnpropagated -> ShowS)
    -> (DnsInfoUnpropagated -> String)
    -> ([DnsInfoUnpropagated] -> ShowS)
    -> Show DnsInfoUnpropagated
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [DnsInfoUnpropagated] -> ShowS
    $cshowList :: [DnsInfoUnpropagated] -> ShowS
    show :: DnsInfoUnpropagated -> String
    $cshow :: DnsInfoUnpropagated -> String
    showsPrec :: Int -> DnsInfoUnpropagated -> ShowS
    $cshowsPrec :: Int -> DnsInfoUnpropagated -> ShowS
    Show, DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    (DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool)
    -> (DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool)
    -> Eq DnsInfoUnpropagated
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    $c/= :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    == :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    $c== :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    Eq, Eq DnsInfoUnpropagated
    Eq DnsInfoUnpropagated =>
    (DnsInfoUnpropagated -> DnsInfoUnpropagated -> Ordering)
    -> (DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool)
    -> (DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool)
    -> (DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool)
    -> (DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool)
    -> (DnsInfoUnpropagated
        -> DnsInfoUnpropagated -> DnsInfoUnpropagated)
    -> (DnsInfoUnpropagated
        -> DnsInfoUnpropagated -> DnsInfoUnpropagated)
    -> Ord DnsInfoUnpropagated
    DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    DnsInfoUnpropagated -> DnsInfoUnpropagated -> Ordering
    DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    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 :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    $cmin :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    max :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    $cmax :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    >= :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    $c>= :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    > :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    $c> :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    <= :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    $c<= :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    < :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    $c< :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Bool
    compare :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Ordering
    $ccompare :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> Ordering
    $cp1Ord :: Eq DnsInfoUnpropagated
    Ord, b -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    NonEmpty DnsInfoUnpropagated -> DnsInfoUnpropagated
    DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    (DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated)
    -> (NonEmpty DnsInfoUnpropagated -> DnsInfoUnpropagated)
    -> (forall b.
        Integral b =>
        b -> DnsInfoUnpropagated -> DnsInfoUnpropagated)
    -> Semigroup DnsInfoUnpropagated
    forall b.
    Integral b =>
    b -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    forall a.
    (a -> a -> a)
    -> (NonEmpty a -> a)
    -> (forall b. Integral b => b -> a -> a)
    -> Semigroup a
    stimes :: b -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    $cstimes :: forall b.
    Integral b =>
    b -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    sconcat :: NonEmpty DnsInfoUnpropagated -> DnsInfoUnpropagated
    $csconcat :: NonEmpty DnsInfoUnpropagated -> DnsInfoUnpropagated
    <> :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    $c<> :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    Sem.Semigroup, Semigroup DnsInfoUnpropagated
    DnsInfoUnpropagated
    Semigroup DnsInfoUnpropagated =>
    DnsInfoUnpropagated
    -> (DnsInfoUnpropagated
        -> DnsInfoUnpropagated -> DnsInfoUnpropagated)
    -> ([DnsInfoUnpropagated] -> DnsInfoUnpropagated)
    -> Monoid DnsInfoUnpropagated
    [DnsInfoUnpropagated] -> DnsInfoUnpropagated
    DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    forall a.
    Semigroup a =>
    a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
    mconcat :: [DnsInfoUnpropagated] -> DnsInfoUnpropagated
    $cmconcat :: [DnsInfoUnpropagated] -> DnsInfoUnpropagated
    mappend :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    $cmappend :: DnsInfoUnpropagated -> DnsInfoUnpropagated -> DnsInfoUnpropagated
    mempty :: DnsInfoUnpropagated
    $cmempty :: DnsInfoUnpropagated
    $cp1Monoid :: Semigroup DnsInfoUnpropagated
    Monoid, Typeable)

    toDnsInfoUnpropagated :: S.Set Record -> DnsInfoUnpropagated
    toDnsInfoUnpropagated :: Set Record -> DnsInfoUnpropagated
    toDnsInfoUnpropagated = Set Record -> DnsInfoUnpropagated
    DnsInfoUnpropagated

    -- | Get all DNS Info.
    getDnsInfo :: Info -> S.Set Record
    getDnsInfo :: Info -> Set Record
    getDnsInfo i :: Info
    i = DnsInfoUnpropagated -> Set Record
    fromDnsInfoUnpropagated (Info -> DnsInfoUnpropagated
    forall v. IsInfo v => Info -> v
    fromInfo Info
    i)
    	Set Record -> Set Record -> Set Record
    forall a. Ord a => Set a -> Set a -> Set a
    `S.union` DnsInfoPropagated -> Set Record
    fromDnsInfoPropagated (Info -> DnsInfoPropagated
    forall v. IsInfo v => Info -> v
    fromInfo Info
    i)

    instance IsInfo DnsInfoUnpropagated where
    	propagateInfo :: DnsInfoUnpropagated -> PropagateInfo
    propagateInfo _ = Bool -> PropagateInfo
    PropagateInfo Bool
    False

    -- | Represents a bind 9 named.conf file.
    data NamedConf = NamedConf
    	{ NamedConf -> String
    confDomain :: Domain
    	, NamedConf -> DnsServerType
    confDnsServerType :: DnsServerType
    	, NamedConf -> String
    confFile :: FilePath
    	, NamedConf -> [IPAddr]
    confMasters :: [IPAddr]
    	, NamedConf -> [IPAddr]
    confAllowTransfer :: [IPAddr]
    	, NamedConf -> [String]
    confLines :: [String]
    	}
    	deriving (Int -> NamedConf -> ShowS
    [NamedConf] -> ShowS
    NamedConf -> String
    (Int -> NamedConf -> ShowS)
    -> (NamedConf -> String)
    -> ([NamedConf] -> ShowS)
    -> Show NamedConf
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [NamedConf] -> ShowS
    $cshowList :: [NamedConf] -> ShowS
    show :: NamedConf -> String
    $cshow :: NamedConf -> String
    showsPrec :: Int -> NamedConf -> ShowS
    $cshowsPrec :: Int -> NamedConf -> ShowS
    Show, NamedConf -> NamedConf -> Bool
    (NamedConf -> NamedConf -> Bool)
    -> (NamedConf -> NamedConf -> Bool) -> Eq NamedConf
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: NamedConf -> NamedConf -> Bool
    $c/= :: NamedConf -> NamedConf -> Bool
    == :: NamedConf -> NamedConf -> Bool
    $c== :: NamedConf -> NamedConf -> Bool
    Eq, Eq NamedConf
    Eq NamedConf =>
    (NamedConf -> NamedConf -> Ordering)
    -> (NamedConf -> NamedConf -> Bool)
    -> (NamedConf -> NamedConf -> Bool)
    -> (NamedConf -> NamedConf -> Bool)
    -> (NamedConf -> NamedConf -> Bool)
    -> (NamedConf -> NamedConf -> NamedConf)
    -> (NamedConf -> NamedConf -> NamedConf)
    -> Ord NamedConf
    NamedConf -> NamedConf -> Bool
    NamedConf -> NamedConf -> Ordering
    NamedConf -> NamedConf -> NamedConf
    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 :: NamedConf -> NamedConf -> NamedConf
    $cmin :: NamedConf -> NamedConf -> NamedConf
    max :: NamedConf -> NamedConf -> NamedConf
    $cmax :: NamedConf -> NamedConf -> NamedConf
    >= :: NamedConf -> NamedConf -> Bool
    $c>= :: NamedConf -> NamedConf -> Bool
    > :: NamedConf -> NamedConf -> Bool
    $c> :: NamedConf -> NamedConf -> Bool
    <= :: NamedConf -> NamedConf -> Bool
    $c<= :: NamedConf -> NamedConf -> Bool
    < :: NamedConf -> NamedConf -> Bool
    $c< :: NamedConf -> NamedConf -> Bool
    compare :: NamedConf -> NamedConf -> Ordering
    $ccompare :: NamedConf -> NamedConf -> Ordering
    $cp1Ord :: Eq NamedConf
    Ord)

    data DnsServerType = Master | Secondary
    	deriving (Int -> DnsServerType -> ShowS
    [DnsServerType] -> ShowS
    DnsServerType -> String
    (Int -> DnsServerType -> ShowS)
    -> (DnsServerType -> String)
    -> ([DnsServerType] -> ShowS)
    -> Show DnsServerType
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [DnsServerType] -> ShowS
    $cshowList :: [DnsServerType] -> ShowS
    show :: DnsServerType -> String
    $cshow :: DnsServerType -> String
    showsPrec :: Int -> DnsServerType -> ShowS
    $cshowsPrec :: Int -> DnsServerType -> ShowS
    Show, DnsServerType -> DnsServerType -> Bool
    (DnsServerType -> DnsServerType -> Bool)
    -> (DnsServerType -> DnsServerType -> Bool) -> Eq DnsServerType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: DnsServerType -> DnsServerType -> Bool
    $c/= :: DnsServerType -> DnsServerType -> Bool
    == :: DnsServerType -> DnsServerType -> Bool
    $c== :: DnsServerType -> DnsServerType -> Bool
    Eq, Eq DnsServerType
    Eq DnsServerType =>
    (DnsServerType -> DnsServerType -> Ordering)
    -> (DnsServerType -> DnsServerType -> Bool)
    -> (DnsServerType -> DnsServerType -> Bool)
    -> (DnsServerType -> DnsServerType -> Bool)
    -> (DnsServerType -> DnsServerType -> Bool)
    -> (DnsServerType -> DnsServerType -> DnsServerType)
    -> (DnsServerType -> DnsServerType -> DnsServerType)
    -> Ord DnsServerType
    DnsServerType -> DnsServerType -> Bool
    DnsServerType -> DnsServerType -> Ordering
    DnsServerType -> DnsServerType -> DnsServerType
    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 :: DnsServerType -> DnsServerType -> DnsServerType
    $cmin :: DnsServerType -> DnsServerType -> DnsServerType
    max :: DnsServerType -> DnsServerType -> DnsServerType
    $cmax :: DnsServerType -> DnsServerType -> DnsServerType
    >= :: DnsServerType -> DnsServerType -> Bool
    $c>= :: DnsServerType -> DnsServerType -> Bool
    > :: DnsServerType -> DnsServerType -> Bool
    $c> :: DnsServerType -> DnsServerType -> Bool
    <= :: DnsServerType -> DnsServerType -> Bool
    $c<= :: DnsServerType -> DnsServerType -> Bool
    < :: DnsServerType -> DnsServerType -> Bool
    $c< :: DnsServerType -> DnsServerType -> Bool
    compare :: DnsServerType -> DnsServerType -> Ordering
    $ccompare :: DnsServerType -> DnsServerType -> Ordering
    $cp1Ord :: Eq DnsServerType
    Ord)

    -- | Represents a bind 9 zone file.
    data Zone = Zone
    	{ Zone -> String
    zDomain :: Domain
    	, Zone -> SOA
    zSOA :: SOA
    	, Zone -> [(BindDomain, Record)]
    zHosts :: [(BindDomain, Record)]
    	}
    	deriving (ReadPrec [Zone]
    ReadPrec Zone
    Int -> ReadS Zone
    ReadS [Zone]
    (Int -> ReadS Zone)
    -> ReadS [Zone] -> ReadPrec Zone -> ReadPrec [Zone] -> Read Zone
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Zone]
    $creadListPrec :: ReadPrec [Zone]
    readPrec :: ReadPrec Zone
    $creadPrec :: ReadPrec Zone
    readList :: ReadS [Zone]
    $creadList :: ReadS [Zone]
    readsPrec :: Int -> ReadS Zone
    $creadsPrec :: Int -> ReadS Zone
    Read, Int -> Zone -> ShowS
    [Zone] -> ShowS
    Zone -> String
    (Int -> Zone -> ShowS)
    -> (Zone -> String) -> ([Zone] -> ShowS) -> Show Zone
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Zone] -> ShowS
    $cshowList :: [Zone] -> ShowS
    show :: Zone -> String
    $cshow :: Zone -> String
    showsPrec :: Int -> Zone -> ShowS
    $cshowsPrec :: Int -> Zone -> ShowS
    Show, Zone -> Zone -> Bool
    (Zone -> Zone -> Bool) -> (Zone -> Zone -> Bool) -> Eq Zone
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Zone -> Zone -> Bool
    $c/= :: Zone -> Zone -> Bool
    == :: Zone -> Zone -> Bool
    $c== :: Zone -> Zone -> Bool
    Eq)

    -- | Every domain has a SOA record, which is big and complicated.
    data SOA = SOA
    	{ SOA -> BindDomain
    sDomain :: BindDomain
    	-- ^ Typically ns1.your.domain
    	, SOA -> SerialNumber
    sSerial :: SerialNumber
    	-- ^ The most important parameter is the serial number,
    	-- which must increase after each change.
    	, SOA -> Integer
    sRefresh :: Integer
    	, SOA -> Integer
    sRetry :: Integer
    	, SOA -> Integer
    sExpire :: Integer
    	, SOA -> Integer
    sNegativeCacheTTL :: Integer
    	}
    	deriving (ReadPrec [SOA]
    ReadPrec SOA
    Int -> ReadS SOA
    ReadS [SOA]
    (Int -> ReadS SOA)
    -> ReadS [SOA] -> ReadPrec SOA -> ReadPrec [SOA] -> Read SOA
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [SOA]
    $creadListPrec :: ReadPrec [SOA]
    readPrec :: ReadPrec SOA
    $creadPrec :: ReadPrec SOA
    readList :: ReadS [SOA]
    $creadList :: ReadS [SOA]
    readsPrec :: Int -> ReadS SOA
    $creadsPrec :: Int -> ReadS SOA
    Read, Int -> SOA -> ShowS
    [SOA] -> ShowS
    SOA -> String
    (Int -> SOA -> ShowS)
    -> (SOA -> String) -> ([SOA] -> ShowS) -> Show SOA
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [SOA] -> ShowS
    $cshowList :: [SOA] -> ShowS
    show :: SOA -> String
    $cshow :: SOA -> String
    showsPrec :: Int -> SOA -> ShowS
    $cshowsPrec :: Int -> SOA -> ShowS
    Show, SOA -> SOA -> Bool
    (SOA -> SOA -> Bool) -> (SOA -> SOA -> Bool) -> Eq SOA
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: SOA -> SOA -> Bool
    $c/= :: SOA -> SOA -> Bool
    == :: SOA -> SOA -> Bool
    $c== :: SOA -> SOA -> Bool
    Eq)

    -- | Types of DNS records.
    --
    -- This is not a complete list, more can be added.
    data Record
    	= Address IPAddr
    	| CNAME BindDomain
    	| MX Int BindDomain
    	| NS BindDomain
    	| TXT String
    	| SRV Word16 Word16 Word16 BindDomain
    	| SSHFP Int Int String
    	| INCLUDE FilePath
    	| PTR ReverseIP
    	deriving (ReadPrec [Record]
    ReadPrec Record
    Int -> ReadS Record
    ReadS [Record]
    (Int -> ReadS Record)
    -> ReadS [Record]
    -> ReadPrec Record
    -> ReadPrec [Record]
    -> Read Record
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Record]
    $creadListPrec :: ReadPrec [Record]
    readPrec :: ReadPrec Record
    $creadPrec :: ReadPrec Record
    readList :: ReadS [Record]
    $creadList :: ReadS [Record]
    readsPrec :: Int -> ReadS Record
    $creadsPrec :: Int -> ReadS Record
    Read, Int -> Record -> ShowS
    [Record] -> ShowS
    Record -> String
    (Int -> Record -> ShowS)
    -> (Record -> String) -> ([Record] -> ShowS) -> Show Record
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Record] -> ShowS
    $cshowList :: [Record] -> ShowS
    show :: Record -> String
    $cshow :: Record -> String
    showsPrec :: Int -> Record -> ShowS
    $cshowsPrec :: Int -> Record -> ShowS
    Show, Record -> Record -> Bool
    (Record -> Record -> Bool)
    -> (Record -> Record -> Bool) -> Eq Record
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Record -> Record -> Bool
    $c/= :: Record -> Record -> Bool
    == :: Record -> Record -> Bool
    $c== :: Record -> Record -> Bool
    Eq, Eq Record
    Eq Record =>
    (Record -> Record -> Ordering)
    -> (Record -> Record -> Bool)
    -> (Record -> Record -> Bool)
    -> (Record -> Record -> Bool)
    -> (Record -> Record -> Bool)
    -> (Record -> Record -> Record)
    -> (Record -> Record -> Record)
    -> Ord Record
    Record -> Record -> Bool
    Record -> Record -> Ordering
    Record -> Record -> Record
    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 :: Record -> Record -> Record
    $cmin :: Record -> Record -> Record
    max :: Record -> Record -> Record
    $cmax :: Record -> Record -> Record
    >= :: Record -> Record -> Bool
    $c>= :: Record -> Record -> Bool
    > :: Record -> Record -> Bool
    $c> :: Record -> Record -> Bool
    <= :: Record -> Record -> Bool
    $c<= :: Record -> Record -> Bool
    < :: Record -> Record -> Bool
    $c< :: Record -> Record -> Bool
    compare :: Record -> Record -> Ordering
    $ccompare :: Record -> Record -> Ordering
    $cp1Ord :: Eq Record
    Ord, Typeable)

    -- | An in-addr.arpa record corresponding to an IPAddr.
    type ReverseIP = String

    reverseIP :: IPAddr -> ReverseIP
    reverseIP :: IPAddr -> String
    reverseIP (IPv4 addr :: String
    addr) = String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate "." ([String] -> [String]
    forall a. [a] -> [a]
    reverse ([String] -> [String]) -> [String] -> [String]
    forall a b. (a -> b) -> a -> b
    $ Char -> String -> [String]
    forall c. Eq c => c -> [c] -> [[c]]
    splitc '.' String
    addr) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ".in-addr.arpa"
    reverseIP addr :: IPAddr
    addr@(IPv6 _) = ShowS
    forall a. [a] -> [a]
    reverse (Char -> ShowS
    forall a. a -> [a] -> [a]
    intersperse '.' ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ String -> String -> ShowS
    forall a. Eq a => [a] -> [a] -> [a] -> [a]
    replace ":" "" ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ IPAddr -> String
    forall t. ConfigurableValue t => t -> String
    val (IPAddr -> String) -> IPAddr -> String
    forall a b. (a -> b) -> a -> b
    $ IPAddr -> IPAddr
    canonicalIP IPAddr
    addr) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ".ip6.arpa"

    -- | Converts an IP address (particularly IPv6) to canonical, fully
    -- expanded form.
    canonicalIP :: IPAddr -> IPAddr
    canonicalIP :: IPAddr -> IPAddr
    canonicalIP (IPv4 addr :: String
    addr) = String -> IPAddr
    IPv4 String
    addr
    canonicalIP (IPv6 addr :: String
    addr) = String -> IPAddr
    IPv6 (String -> IPAddr) -> String -> IPAddr
    forall a b. (a -> b) -> a -> b
    $ String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate ":" ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ ShowS -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map ShowS
    canonicalGroup ([String] -> [String]) -> [String] -> [String]
    forall a b. (a -> b) -> a -> b
    $ Char -> String -> [String]
    forall c. Eq c => c -> [c] -> [[c]]
    splitc ':' (String -> [String]) -> String -> [String]
    forall a b. (a -> b) -> a -> b
    $ ShowS
    replaceImplicitGroups String
    addr
      where
    	canonicalGroup :: ShowS
    canonicalGroup g :: String
    g
    		| Int
    l Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= 4    = Int -> Char -> String
    forall a. Int -> a -> [a]
    replicate (4 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    l) '0' String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    g
    		| Bool
    otherwise = ShowS
    forall a. HasCallStack => String -> a
    error ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ "IPv6 group " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    g String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ "as more than 4 hex digits"
    	  where
    		l :: Int
    l = String -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length String
    g
    	emptyGroups :: Int -> String
    emptyGroups n :: Int
    n = ShowS -> String -> [String]
    forall a. (a -> a) -> a -> [a]
    iterate (String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ":") "" [String] -> Int -> String
    forall a. [a] -> Int -> a
    !! Int
    n
    	numberOfImplicitGroups :: String -> Int
    numberOfImplicitGroups a :: String
    a = 8 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - [String] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length (Char -> String -> [String]
    forall c. Eq c => c -> [c] -> [[c]]
    splitc ':' (String -> [String]) -> String -> [String]
    forall a b. (a -> b) -> a -> b
    $ String -> String -> ShowS
    forall a. Eq a => [a] -> [a] -> [a] -> [a]
    replace "::" "" String
    a)
    	replaceImplicitGroups :: ShowS
    replaceImplicitGroups a :: String
    a = [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ [String] -> [String]
    aux ([String] -> [String]) -> [String] -> [String]
    forall a b. (a -> b) -> a -> b
    $ String -> String -> [String]
    forall a. Eq a => [a] -> [a] -> [[a]]
    split "::" String
    a
    	  where
    		aux :: [String] -> [String]
    aux [] = []
    		aux (x :: String
    x : xs :: [String]
    xs) = String
    x String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : Int -> String
    emptyGroups (String -> Int
    numberOfImplicitGroups String
    a) String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : [String]
    xs

    getIPAddr :: Record -> Maybe IPAddr
    getIPAddr :: Record -> Maybe IPAddr
    getIPAddr (Address addr :: IPAddr
    addr) = IPAddr -> Maybe IPAddr
    forall a. a -> Maybe a
    Just IPAddr
    addr
    getIPAddr _ = Maybe IPAddr
    forall a. Maybe a
    Nothing

    getCNAME :: Record -> Maybe BindDomain
    getCNAME :: Record -> Maybe BindDomain
    getCNAME (CNAME d :: BindDomain
    d) = BindDomain -> Maybe BindDomain
    forall a. a -> Maybe a
    Just BindDomain
    d
    getCNAME _ = Maybe BindDomain
    forall a. Maybe a
    Nothing

    getNS :: Record -> Maybe BindDomain
    getNS :: Record -> Maybe BindDomain
    getNS (NS d :: BindDomain
    d) = BindDomain -> Maybe BindDomain
    forall a. a -> Maybe a
    Just BindDomain
    d
    getNS _ = Maybe BindDomain
    forall a. Maybe a
    Nothing

    -- | Bind serial numbers are unsigned, 32 bit integers.
    type SerialNumber = Word32

    -- | Domains in the zone file must end with a period if they are absolute.
    --
    -- Let's use a type to keep absolute domains straight from relative
    -- domains.
    --
    -- The RootDomain refers to the top level of the domain, so can be used
    -- to add nameservers, MX's, etc to a domain.
    data BindDomain = RelDomain Domain | AbsDomain Domain | RootDomain
    	deriving (ReadPrec [BindDomain]
    ReadPrec BindDomain
    Int -> ReadS BindDomain
    ReadS [BindDomain]
    (Int -> ReadS BindDomain)
    -> ReadS [BindDomain]
    -> ReadPrec BindDomain
    -> ReadPrec [BindDomain]
    -> Read BindDomain
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [BindDomain]
    $creadListPrec :: ReadPrec [BindDomain]
    readPrec :: ReadPrec BindDomain
    $creadPrec :: ReadPrec BindDomain
    readList :: ReadS [BindDomain]
    $creadList :: ReadS [BindDomain]
    readsPrec :: Int -> ReadS BindDomain
    $creadsPrec :: Int -> ReadS BindDomain
    Read, Int -> BindDomain -> ShowS
    [BindDomain] -> ShowS
    BindDomain -> String
    (Int -> BindDomain -> ShowS)
    -> (BindDomain -> String)
    -> ([BindDomain] -> ShowS)
    -> Show BindDomain
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [BindDomain] -> ShowS
    $cshowList :: [BindDomain] -> ShowS
    show :: BindDomain -> String
    $cshow :: BindDomain -> String
    showsPrec :: Int -> BindDomain -> ShowS
    $cshowsPrec :: Int -> BindDomain -> ShowS
    Show, BindDomain -> BindDomain -> Bool
    (BindDomain -> BindDomain -> Bool)
    -> (BindDomain -> BindDomain -> Bool) -> Eq BindDomain
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: BindDomain -> BindDomain -> Bool
    $c/= :: BindDomain -> BindDomain -> Bool
    == :: BindDomain -> BindDomain -> Bool
    $c== :: BindDomain -> BindDomain -> Bool
    Eq, Eq BindDomain
    Eq BindDomain =>
    (BindDomain -> BindDomain -> Ordering)
    -> (BindDomain -> BindDomain -> Bool)
    -> (BindDomain -> BindDomain -> Bool)
    -> (BindDomain -> BindDomain -> Bool)
    -> (BindDomain -> BindDomain -> Bool)
    -> (BindDomain -> BindDomain -> BindDomain)
    -> (BindDomain -> BindDomain -> BindDomain)
    -> Ord BindDomain
    BindDomain -> BindDomain -> Bool
    BindDomain -> BindDomain -> Ordering
    BindDomain -> BindDomain -> BindDomain
    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 :: BindDomain -> BindDomain -> BindDomain
    $cmin :: BindDomain -> BindDomain -> BindDomain
    max :: BindDomain -> BindDomain -> BindDomain
    $cmax :: BindDomain -> BindDomain -> BindDomain
    >= :: BindDomain -> BindDomain -> Bool
    $c>= :: BindDomain -> BindDomain -> Bool
    > :: BindDomain -> BindDomain -> Bool
    $c> :: BindDomain -> BindDomain -> Bool
    <= :: BindDomain -> BindDomain -> Bool
    $c<= :: BindDomain -> BindDomain -> Bool
    < :: BindDomain -> BindDomain -> Bool
    $c< :: BindDomain -> BindDomain -> Bool
    compare :: BindDomain -> BindDomain -> Ordering
    $ccompare :: BindDomain -> BindDomain -> Ordering
    $cp1Ord :: Eq BindDomain
    Ord)

    domainHostName :: BindDomain -> Maybe HostName
    domainHostName :: BindDomain -> Maybe String
    domainHostName (RelDomain d :: String
    d) = String -> Maybe String
    forall a. a -> Maybe a
    Just String
    d
    domainHostName (AbsDomain d :: String
    d) = String -> Maybe String
    forall a. a -> Maybe a
    Just String
    d
    domainHostName RootDomain = Maybe String
    forall a. Maybe a
    Nothing

    newtype NamedConfMap = NamedConfMap (M.Map Domain NamedConf)
    	deriving (NamedConfMap -> NamedConfMap -> Bool
    (NamedConfMap -> NamedConfMap -> Bool)
    -> (NamedConfMap -> NamedConfMap -> Bool) -> Eq NamedConfMap
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: NamedConfMap -> NamedConfMap -> Bool
    $c/= :: NamedConfMap -> NamedConfMap -> Bool
    == :: NamedConfMap -> NamedConfMap -> Bool
    $c== :: NamedConfMap -> NamedConfMap -> Bool
    Eq, Eq NamedConfMap
    Eq NamedConfMap =>
    (NamedConfMap -> NamedConfMap -> Ordering)
    -> (NamedConfMap -> NamedConfMap -> Bool)
    -> (NamedConfMap -> NamedConfMap -> Bool)
    -> (NamedConfMap -> NamedConfMap -> Bool)
    -> (NamedConfMap -> NamedConfMap -> Bool)
    -> (NamedConfMap -> NamedConfMap -> NamedConfMap)
    -> (NamedConfMap -> NamedConfMap -> NamedConfMap)
    -> Ord NamedConfMap
    NamedConfMap -> NamedConfMap -> Bool
    NamedConfMap -> NamedConfMap -> Ordering
    NamedConfMap -> NamedConfMap -> NamedConfMap
    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 :: NamedConfMap -> NamedConfMap -> NamedConfMap
    $cmin :: NamedConfMap -> NamedConfMap -> NamedConfMap
    max :: NamedConfMap -> NamedConfMap -> NamedConfMap
    $cmax :: NamedConfMap -> NamedConfMap -> NamedConfMap
    >= :: NamedConfMap -> NamedConfMap -> Bool
    $c>= :: NamedConfMap -> NamedConfMap -> Bool
    > :: NamedConfMap -> NamedConfMap -> Bool
    $c> :: NamedConfMap -> NamedConfMap -> Bool
    <= :: NamedConfMap -> NamedConfMap -> Bool
    $c<= :: NamedConfMap -> NamedConfMap -> Bool
    < :: NamedConfMap -> NamedConfMap -> Bool
    $c< :: NamedConfMap -> NamedConfMap -> Bool
    compare :: NamedConfMap -> NamedConfMap -> Ordering
    $ccompare :: NamedConfMap -> NamedConfMap -> Ordering
    $cp1Ord :: Eq NamedConfMap
    Ord, Int -> NamedConfMap -> ShowS
    [NamedConfMap] -> ShowS
    NamedConfMap -> String
    (Int -> NamedConfMap -> ShowS)
    -> (NamedConfMap -> String)
    -> ([NamedConfMap] -> ShowS)
    -> Show NamedConfMap
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [NamedConfMap] -> ShowS
    $cshowList :: [NamedConfMap] -> ShowS
    show :: NamedConfMap -> String
    $cshow :: NamedConfMap -> String
    showsPrec :: Int -> NamedConfMap -> ShowS
    $cshowsPrec :: Int -> NamedConfMap -> ShowS
    Show, Typeable)

    instance IsInfo NamedConfMap where
    	propagateInfo :: NamedConfMap -> PropagateInfo
    propagateInfo _ = Bool -> PropagateInfo
    PropagateInfo Bool
    False

    -- | Adding a Master NamedConf stanza for a particular domain always
    -- overrides an existing Secondary stanza for that domain, while a
    -- Secondary stanza is only added when there is no existing Master stanza.
    instance Sem.Semigroup NamedConfMap where
    	NamedConfMap old :: Map String NamedConf
    old <> :: NamedConfMap -> NamedConfMap -> NamedConfMap
    <> NamedConfMap new :: Map String NamedConf
    new = Map String NamedConf -> NamedConfMap
    NamedConfMap (Map String NamedConf -> NamedConfMap)
    -> Map String NamedConf -> NamedConfMap
    forall a b. (a -> b) -> a -> b
    $
    		(NamedConf -> NamedConf -> NamedConf)
    -> Map String NamedConf
    -> Map String NamedConf
    -> Map String NamedConf
    forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
    M.unionWith NamedConf -> NamedConf -> NamedConf
    combiner Map String NamedConf
    new Map String NamedConf
    old
    	  where
    		combiner :: NamedConf -> NamedConf -> NamedConf
    combiner n :: NamedConf
    n o :: NamedConf
    o = case (NamedConf -> DnsServerType
    confDnsServerType NamedConf
    n, NamedConf -> DnsServerType
    confDnsServerType NamedConf
    o) of
    			(Secondary, Master) -> NamedConf
    o
    			_  -> NamedConf
    n

    instance Monoid NamedConfMap where
    	mempty :: NamedConfMap
    mempty = Map String NamedConf -> NamedConfMap
    NamedConfMap Map String NamedConf
    forall k a. Map k a
    M.empty
    	mappend :: NamedConfMap -> NamedConfMap -> NamedConfMap
    mappend = NamedConfMap -> NamedConfMap -> NamedConfMap
    forall a. Semigroup a => a -> a -> a
    (Sem.<>)

    instance Empty NamedConfMap where
    	isEmpty :: NamedConfMap -> Bool
    isEmpty (NamedConfMap m :: Map String NamedConf
    m) = Map String NamedConf -> Bool
    forall t. Empty t => t -> Bool
    isEmpty Map String NamedConf
    m

    fromNamedConfMap :: NamedConfMap -> M.Map Domain NamedConf
    fromNamedConfMap :: NamedConfMap -> Map String NamedConf
    fromNamedConfMap (NamedConfMap m :: Map String NamedConf
    m) = Map String NamedConf
    m