module Network.HTTP.Lucu.SocketLike
    ( SocketLike(..)
    )
    where

import qualified Network.Socket as So
import           Network.HTTP.Lucu.HandleLike
import qualified OpenSSL.Session as SSL
import qualified System.IO as I


class (HandleLike (Handle s)) => SocketLike s where
    type Handle s :: *
    accept        :: s -> IO (Handle s, So.SockAddr)
    socketPort    :: s -> IO So.PortNumber


instance SocketLike So.Socket where
    type Handle So.Socket = I.Handle

    accept soSelf
        = do (soPeer, addr) <- So.accept soSelf
             hPeer          <- So.socketToHandle soPeer I.ReadWriteMode
             return (hPeer, addr)

    socketPort = So.socketPort


instance SocketLike (SSL.SSLContext, So.Socket) where
    type Handle (SSL.SSLContext, So.Socket) = SSL.SSL

    accept (ctx, soSelf)
        = do (soPeer, addr) <- So.accept soSelf
             ssl            <- SSL.connection ctx soPeer
             SSL.accept ssl
             return (ssl, addr)

    socketPort = So.socketPort . snd