module Dropbox.Certificates.TH 
  ( pem
  , pemFile
  , x509
  , x509File
  ) where
import Data.ByteString.Char8 (pack)
import Data.ByteString.Lazy  (fromChunks)
import Data.PEM              (PEM(..), pemParseBS)
import Data.Certificate.X509 (X509(..), decodeCertificate)
import Language.Haskell.TH.Quote
rightsOrFirstLeft :: [Either a b] -> Either a [b]
rightsOrFirstLeft = foldr f (Right [])
    where
        f (Left e) _ = Left e
        f _ (Left e) = Left e
        f (Right v) (Right vs) = Right (v:vs)
pem :: QuasiQuoter
pem = QuasiQuoter { quoteExp = \s -> [| parsePem s |] }
pemFile :: QuasiQuoter
pemFile = quoteFile pem
parsePem :: String -> [PEM]
parsePem s = case pemParseBS $ pack s of
               Left err -> error $ "Failed to parse PEM file: " ++ err
               Right x -> x
x509 :: QuasiQuoter
x509 = QuasiQuoter { quoteExp = \s -> [| decodeCert . parsePem $ s |] } 
x509File :: QuasiQuoter
x509File = quoteFile x509
decodeCert :: [PEM] -> [X509]
decodeCert pems = 
    let es = [decodeCertificate (fromChunks [stuff]) | PEM _ _ stuff <- pems]
    in  case rightsOrFirstLeft es of
          Left err -> error $ "Failed to decode X509 file: " ++ err
          Right x509s -> x509s