-- 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