import           Data.Maybe
 import           Network
 import           Network.HTTP.Lucu
+import           OpenSSL
 import           Rakka.Environment
 import           Rakka.Resource.CheckAuth
 import           Rakka.Resource.Index
 
 
 main :: IO ()
-main = withSubversion $
+main = withOpenSSL $
+       withSubversion $
        do (opts, nonOpts, errors) <- return . getOpt Permute options =<< getArgs
 
           when (not $ null errors)
 
 Name:          Rakka
 Synopsis:      Wiki engine with Subversion backend
 Description:
-    FIXME: write this
+    Rakka is a wiki engine with Subversion backend. Its syntax is
+    similar to MediaWiki.
 Version:       0.1
 License:       PublicDomain
 Author:        PHO <phonohawk at ps dot sakura dot ne dot jp>
 Maintainer:    PHO <phonohawk at ps dot sakura dot ne dot jp>
 Stability:     experimental
-Homepage:      http://ccm.sherry.jp/Rakka/
+Homepage:      http://rakka.cielonegro.org/
 Category:      Web
 Tested-With:   GHC == 6.6.1
 Cabal-Version: >= 1.2
 
 Executable rakka
     Build-Depends:
-        Crypto, FileManip, HTTP, HUnit, HsHyperEstraier, HsSVN, Lucu,
-        base, bytestring, containers, dataenc, directory, utf8-string,
-        filepath, hslogger, hxt, magic, mtl, network, parsec, stm,
-        time, unix, zlib
+        FileManip, HTTP, HUnit, HsHyperEstraier, HsOpenSSL, HsSVN,
+        Lucu, base, bytestring, containers, dataenc, directory,
+        utf8-string, filepath, hslogger, hxt, magic, mtl, network,
+        parsec, stm, time, unix, zlib
     Main-Is:
         Main.hs
     Other-Modules:
 
     )
     where
 
-import qualified Codec.Binary.Base64 as B64
 import qualified Codec.Binary.UTF8.String as UTF8
 import           Control.Concurrent.STM
 import           Control.Monad.Trans
-import           Data.Digest.SHA2
+import qualified Data.ByteString as B
 import           Data.Map (Map)
 import qualified Data.Map as M hiding (Map)
 import           Data.Maybe
-import           Data.Word
+import           OpenSSL.EVP.Base64
+import           OpenSSL.EVP.Digest
 import           Rakka.SystemConfig
 import           System.Directory
 import           System.FilePath
       }
 
 
-type UserMap = Map String [Word8]
+type UserMap = Map String String
 
 
 mkAuthDB :: FilePath -> IO AuthDB
 
 isValidPair :: MonadIO m => AuthDB -> String -> String -> m Bool
 isValidPair adb name pass
-    = let hash = toOctets $ sha256 $ UTF8.encode pass
-      in
-        liftIO $ atomically $ do m <- readTVar (adbUserMap adb)
-                                 return (M.lookup name m == Just hash)
+    = liftIO $ do sha1 <- return . fromJust =<< getDigestByName "SHA1"
+                  let hash = digestBS sha1 $ B.pack $ UTF8.encode pass
+                  atomically $ do m <- readTVar (adbUserMap adb)
+                                  return (M.lookup name m == Just hash)
 
 
 loadUserMap :: FilePath -> IO UserMap
                       return . M.fromList . map decodePair . fromJust . deserializeStringPairs
                   else
                       return M.empty
-         return (initMap m)
+         sha1  <- return . fromJust =<< getDigestByName "SHA1"
+         return (initMap sha1 m)
     where
-      decodePair :: (String, String) -> (String, [Word8])
+      decodePair :: (String, String) -> (String, String)
       decodePair (name, b64Hash)
-          = (UTF8.decodeString name, fromJust $ B64.decode b64Hash)
+          = (UTF8.decodeString name, decodeBase64 b64Hash)
 
-      initMap :: UserMap -> UserMap
-      initMap m
+      initMap :: Digest -> UserMap -> UserMap
+      initMap sha1 m
           | M.null m  = let name = "root"
-                            hash = toOctets $ sha256 ([] :: [Word8])
+                            hash = digest sha1 ""
                         in
                           M.singleton name hash
           | otherwise = m
 
     )
     where
 
-import qualified Codec.Binary.Base64 as B64
 import qualified Codec.Binary.UTF8.String as UTF8
 import           Control.Arrow
 import           Control.Arrow.ArrowIO
 import           Control.Arrow.ArrowList
 import qualified Data.ByteString.Lazy as Lazy (ByteString)
 import qualified Data.ByteString.Lazy as L hiding (ByteString)
+import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString)
 import           Data.Char
 import           Data.Map (Map)
 import qualified Data.Map as M
 import           Data.Time
 import           Network.HTTP.Lucu hiding (redirect)
 import           Network.URI hiding (fragment)
+import           OpenSSL.EVP.Base64
 import           Rakka.Utils
 import           Rakka.W3CDateTime
 import           Subversion.Types
                           )
                        += ( if entityIsBinary page then
                                 ( eelem "binaryData"
-                                  += txt (B64.encode $ L.unpack $ entityContent page)
+                                  += txt (L8.unpack $ encodeBase64LBS $ entityContent page)
                                 )
                             else
                                 ( eelem "textData"
 
           let (isBinary, content)
                   = case (textData, binaryData) of
-                      (Just text, Nothing    ) -> (False, L.pack $ UTF8.encode text )
-                      (Nothing  , Just binary) -> (True , L.pack $ fromJust $ B64.decode $ dropWhitespace binary)
+                      (Just text, Nothing    ) -> (False, L.pack $ UTF8.encode text)
+                      (Nothing  , Just binary) -> (True , L8.pack $ decodeBase64 $ dropWhitespace binary)
                       _                        -> error "one of textData or binaryData is required"
               mimeType
                   =  if isBinary then
 
     )
     where
 
-import qualified Codec.Binary.Base64 as B64
 import           Control.Arrow
 import           Control.Arrow.ArrowIO
 import           Control.Arrow.ArrowList
 import           Control.Monad.Trans
-import qualified Data.ByteString.Lazy as Lazy (ByteString, pack)
-import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString)
+import qualified Data.ByteString.Lazy as Lazy
 import           Data.Maybe
 import           Network.HTTP.Lucu
 import           Network.HTTP.Lucu.Utils
+import           OpenSSL.EVP.Base64
 import           Rakka.Environment
 import           Rakka.Page
 import           Rakka.Utils
 
          let (bin, cType) = case cTypeM of
                               Just (MIMEType "application" "x-rakka-base64-stream" _)
-                                  -> let b = Lazy.pack $ fromJust $ B64.decode $ L8.unpack entity
+                                  -> let b = decodeBase64LBS entity
                                      in
                                        (b, guessMIMEType b)
                               Just t
 
     )
     where
 
-import qualified Codec.Binary.Base64 as B64
 import qualified Codec.Binary.UTF8.String as UTF8
 import           Control.Arrow
 import           Control.Arrow.ArrowIO
 import           Control.Arrow.ArrowList
 import qualified Data.ByteString.Lazy as Lazy
+import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString)
 import           Data.Map (Map)
 import qualified Data.Map as M
 import           Data.Maybe
 import           Network.HTTP.Lucu
 import           Network.URI
+import           OpenSSL.EVP.Base64
 import           Rakka.Page
 import           Rakka.Storage
 import           Rakka.SystemConfig
       binToURI m b
           = nullURI {
               uriScheme = "data:"
-            , uriPath   = show m ++ ";base64," ++ B64.encode (Lazy.unpack b)
+            , uriPath   = show m ++ ";base64," ++ (L8.unpack $ encodeBase64LBS b)
             }