module Data.BidiSpec.Extras
    ( wrapBase16, wrapBase64
    , fromPair, fromTriple, fromQuadruple, fromQuintuple
    , toPair, toTriple, toQuadruple, toQuintuple
    )
where

----------------------------------------
-- STDLIB
----------------------------------------
import Data.Word (Word8)
import Data.Char (toUpper)

import qualified Data.ByteString.Lazy as BSL

----------------------------------------
-- SITE-PACKAGES
----------------------------------------
import qualified Codec.Binary.Base16 as Base16
import qualified Codec.Binary.Base64 as Base64

baseToStr :: ([Word8] -> String) -> BSL.ByteString -> String
baseToStr f = f . BSL.unpack

strToBase64 :: (String -> Maybe [Word8]) -> String -> Maybe BSL.ByteString
strToBase64 f = fmap BSL.pack . f

strToBase16 :: (String -> Maybe [Word8]) -> String -> Maybe BSL.ByteString
strToBase16 f s = fmap BSL.pack $ f s''
    where
      s' = map toUpper s
      s'' = if length s' `mod` 2 == 0 then s' else '0' : s'

wrapBase64 :: (String -> Maybe BSL.ByteString, BSL.ByteString -> String)
wrapBase64 = (strToBase64 Base64.decode, baseToStr Base64.encode)

wrapBase16 :: (String -> Maybe BSL.ByteString, BSL.ByteString -> String)
wrapBase16 = (strToBase16 Base16.decode, baseToStr Base16.encode)


fromPair :: (a -> b -> c) -> (a, b) -> c
fromPair f ~(a, b) = f a b

fromTriple :: (a -> b -> c -> d) -> (a, b, c) -> d
fromTriple f ~(a, b, c) = f a b c

fromQuadruple :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
fromQuadruple f ~(a, b, c, d) = f a b c d

fromQuintuple :: (a -> b -> c -> d -> e -> f) -> (a, b, c, d, e) -> f
fromQuintuple f ~(a, b, c, d, e) = f a b c d e


toPair :: (t -> a, t -> b) -> t -> (a, b)
toPair (f, g) x = (f x, g x)

toTriple :: (t -> a, t -> b, t -> c) -> t -> (a, b, c)
toTriple (f, g, h) x = (f x, g x, h x)

toQuadruple :: (t -> a, t -> b, t -> c, t -> d) -> t -> (a, b, c, d)
toQuadruple (f, g, h, i) x = (f x, g x, h x, i x)

toQuintuple :: (t -> a, t -> b, t -> c, t -> d, t -> e) -> t -> (a, b, c, d, e)
toQuintuple (f, g, h, i, j) x = (f x, g x, h x, i x, j x)