-- Tahin
-- Copyright (C) 2015-2016 Moritz Schulte <mtesseract@silverratio.net>

{-# LANGUAGE OverloadedStrings          #-}

module Crypto.Tahin ( TahinPassword
                    , TahinMasterPassword
                    , TahinIdentifier
                    , TahinTransformer
                    , tahin ) where

import qualified Data.ByteString.Base64   as B64
import qualified Data.ByteString.Char8    as BS8
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import           Data.Text (Text)

-- | TahinMasterPassword is used for holding a master password.
type TahinMasterPassword = Text

-- | TahinPassword is used for passwords generated by Tahin.
type TahinPassword = Text

-- | A TahinIdentifier is used for holding a '(service) identifier'.
type TahinIdentifier = Text

-- | A 'TahinTransformer' is a function mapping a
-- 'TahinMasterPassword' together with a 'TahinIdentifier' to a
-- 'TahinPassword'.
type TahinTransformer = TahinMasterPassword -> TahinIdentifier -> TahinPassword

-------------------------
-- Main tahin function --
-------------------------

-- | Given a hash function and a maximum length, return a
-- 'TahinTransformer'.
tahin :: (BS8.ByteString -> BS8.ByteString) -> Int -> TahinTransformer
tahin hash len =
  curry (T.take len . TE.decodeUtf8 . B64.encode . hash . TE.encodeUtf8 . intercal)
  where intercal (pw, identifier) = T.intercalate " " [pw, identifier]