--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
--   http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--

module Thrift.Server
    ( runBasicServer
    , runThreadedServer
    ) where

import Control.Concurrent ( forkIO )
import Control.Exception
import Control.Monad ( forever, when )

import Network

import System.IO

import Thrift
import Thrift.Transport.Handle
import Thrift.Protocol.Binary


-- | A threaded sever that is capable of using any Transport or Protocol
-- instances.
runThreadedServer :: (Transport t, Protocol i, Protocol o)
                  => (Socket -> IO (i t, o t))
                  -> h
                  -> (h -> (i t, o t) -> IO Bool)
                  -> PortID
                  -> IO a
runThreadedServer accepter hand proc port = do
    socket <- listenOn port
    acceptLoop (accepter socket) (proc hand)

-- | A basic threaded binary protocol socket server.
runBasicServer :: h
               -> (h -> (BinaryProtocol Handle, BinaryProtocol Handle) -> IO Bool)
               -> PortNumber
               -> IO a
runBasicServer hand proc port = runThreadedServer binaryAccept hand proc (PortNumber port)
  where binaryAccept s = do
            (h, _, _) <- accept s
            return (BinaryProtocol h, BinaryProtocol h)

acceptLoop :: IO t -> (t -> IO Bool) -> IO a
acceptLoop accepter proc = forever $
    do ps <- accepter
       forkIO $ handle (\(e :: SomeException) -> return ())
                  (loop $ proc ps)
  where loop m = do { continue <- m; when continue (loop m) }
