    -- TK.hs: OpenPGP (RFC4880) transferable key data type
    -- Copyright © 2012-2016  Clint Adams
    -- This software is released under the terms of the Expat license.
    -- (See the LICENSE file).
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE TemplateHaskell #-}

    module Codec.Encryption.OpenPGP.Types.Internal.TK where

    import GHC.Generics (Generic)

    import Codec.Encryption.OpenPGP.Types.Internal.Base
    import Codec.Encryption.OpenPGP.Types.Internal.PKITypes
    import Codec.Encryption.OpenPGP.Types.Internal.Pkt

    import Control.Lens (makeLenses)
    import qualified Data.Aeson.TH as ATH
    import Data.Data (Data)
    import Data.IxSet.Typed (IxSet)
    import Data.Ord (comparing)
    import Data.Text (Text)
    import Data.Typeable (Typeable)

    data TK =
      TK
        { TK -> (PKPayload, Maybe SKAddendum)
    _tkKey :: (PKPayload, Maybe SKAddendum)
        , TK -> [SignaturePayload]
    _tkRevs :: [SignaturePayload]
        , TK -> [(Text, [SignaturePayload])]
    _tkUIDs :: [(Text, [SignaturePayload])]
        , TK -> [([UserAttrSubPacket], [SignaturePayload])]
    _tkUAts :: [([UserAttrSubPacket], [SignaturePayload])]
        , TK -> [(Pkt, [SignaturePayload])]
    _tkSubs :: [(Pkt, [SignaturePayload])]
        }
      deriving (Typeable TK
    Typeable TK =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> TK -> c TK)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c TK)
    -> (TK -> Constr)
    -> (TK -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c TK))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TK))
    -> ((forall b. Data b => b -> b) -> TK -> TK)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TK -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TK -> r)
    -> (forall u. (forall d. Data d => d -> u) -> TK -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> TK -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> TK -> m TK)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> TK -> m TK)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> TK -> m TK)
    -> Data TK
    TK -> Constr
    TK -> DataType
    (forall b. Data b => b -> b) -> TK -> TK
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> TK -> u
    forall u. (forall d. Data d => d -> u) -> TK -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TK -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TK -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TK -> m TK
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TK -> m TK
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TK
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TK -> c TK
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TK)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TK)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TK -> c TK
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TK -> c TK
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TK
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TK
    $ctoConstr :: TK -> Constr
    toConstr :: TK -> Constr
    $cdataTypeOf :: TK -> DataType
    dataTypeOf :: TK -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TK)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TK)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TK)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TK)
    $cgmapT :: (forall b. Data b => b -> b) -> TK -> TK
    gmapT :: (forall b. Data b => b -> b) -> TK -> TK
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TK -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TK -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TK -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TK -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> TK -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> TK -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TK -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TK -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TK -> m TK
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TK -> m TK
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TK -> m TK
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TK -> m TK
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TK -> m TK
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TK -> m TK
    Data, TK -> TK -> Bool
    (TK -> TK -> Bool) -> (TK -> TK -> Bool) -> Eq TK
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: TK -> TK -> Bool
    == :: TK -> TK -> Bool
    $c/= :: TK -> TK -> Bool
    /= :: TK -> TK -> Bool
    Eq, (forall x. TK -> Rep TK x)
    -> (forall x. Rep TK x -> TK) -> Generic TK
    forall x. Rep TK x -> TK
    forall x. TK -> Rep TK x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. TK -> Rep TK x
    from :: forall x. TK -> Rep TK x
    $cto :: forall x. Rep TK x -> TK
    to :: forall x. Rep TK x -> TK
    Generic, Int -> TK -> ShowS
    [TK] -> ShowS
    TK -> String
    (Int -> TK -> ShowS)
    -> (TK -> String) -> ([TK] -> ShowS) -> Show TK
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> TK -> ShowS
    showsPrec :: Int -> TK -> ShowS
    $cshow :: TK -> String
    show :: TK -> String
    $cshowList :: [TK] -> ShowS
    showList :: [TK] -> ShowS
    Show, Typeable)

    instance Ord TK where
      compare :: TK -> TK -> Ordering
    compare = (TK -> (PKPayload, Maybe SKAddendum)) -> TK -> TK -> Ordering
    forall a b. Ord a => (b -> a) -> b -> b -> Ordering
    comparing TK -> (PKPayload, Maybe SKAddendum)
    _tkKey -- FIXME: is this ridiculous?

    $(ATH.deriveToJSON ATH.defaultOptions ''TK)

    type KeyringIxs = '[ EightOctetKeyId, TwentyOctetFingerprint, Text]

    type Keyring = IxSet KeyringIxs TK

    $(makeLenses ''TK)