    -- KeySelection.hs: OpenPGP (RFC4880) ways to ask for keys
    -- Copyright © 2014  Clint Adams
    -- This software is released under the terms of the Expat license.
    -- (See the LICENSE file).

    {-# LANGUAGE OverloadedStrings #-}

    module Codec.Encryption.OpenPGP.KeySelection (
       parseEightOctetKeyId
     , parseFingerprint
    ) where

    import qualified Data.ByteString as B
    import Codec.Encryption.OpenPGP.Internal (integerToBEBS)
    import Codec.Encryption.OpenPGP.Types
    import Control.Applicative (optional, (<$>), (*>))
    import Control.Monad ((<=<))
    import Data.Attoparsec.Text (asciiCI, count, hexadecimal, inClass, parseOnly, Parser, satisfy)
    import Data.Text (Text, toUpper)
    import qualified Data.Text as T

    parseEightOctetKeyId :: Text -> Either String EightOctetKeyId
    parseEightOctetKeyId = fmap EightOctetKeyId . (parseOnly hexes <=< parseOnly (hexPrefix *> hexen 16)) . toUpper

    parseFingerprint :: Text -> Either String TwentyOctetFingerprint
    parseFingerprint = fmap TwentyOctetFingerprint . (parseOnly hexes <=< parseOnly (hexen 40)) . toUpper . T.filter (/=' ')

    hexPrefix :: Parser (Maybe Text)
    hexPrefix = optional (asciiCI "0x")

    hexen :: Int -> Parser Text
    hexen n = T.pack <$> count n (satisfy (inClass "A-F0-9"))

    hexes :: Parser B.ByteString
    hexes = integerToBEBS <$> hexadecimal