content: {-# LANGUAGE CPP                 #-}
  {-# LANGUAGE ScopedTypeVariables #-}
  
  module Main where
  
  import           Control.Concurrent                             (killThread, takeMVar)
  import qualified Control.Exception                              as E
  import           Control.Monad                                  (liftM)
  import           Data.Maybe                                     (maybeToList)
  #if !MIN_VERSION_network(2,7,0)
  import           Network                                        (withSocketsDo)
  #endif
  import           System.Environment
  import           Test.Framework                                 (defaultMain, testGroup)
  ------------------------------------------------------------------------------
  import qualified Snap.Internal.Http.Server.TLS                  as TLS
  ------------------------------------------------------------------------------
  import qualified Snap.Internal.Http.Server.Address.Tests        as Address
  import qualified Snap.Internal.Http.Server.Parser.Tests         as Parser
  import qualified Snap.Internal.Http.Server.Session.Tests        as Session
  import qualified Snap.Internal.Http.Server.Socket.Tests         as Socket
  import qualified Snap.Internal.Http.Server.TimeoutManager.Tests as TimeoutManager
  import           Snap.Test.Common                               (eatException)
  #ifdef HAS_SENDFILE
  import qualified System.SendFile.Tests                          as SendFile
  #endif
  import qualified Test.Blackbox
  
  #if MIN_VERSION_network(2,7,0)
  withSocketsDo :: IO a -> IO a
  withSocketsDo = id
  #endif
  
  ------------------------------------------------------------------------------
  main :: IO ()
  main = withSocketsDo $ TLS.withTLS $ eatException $
         E.bracket (Test.Blackbox.startTestServers)
                   cleanup
                   (\tinfos -> do
                       let blackboxTests = bbox tinfos
                       defaultMain $ tests ++ blackboxTests
                   )
    where
      cleanup (x, y, m) = do
          let backends = [x, y] ++ maybeToList m
          mapM_ (killThread . (\(a, _, _) -> a)) backends
          mapM_ (takeMVar . (\(_, _, a) -> a)) backends
  
      bbox ((_, port, _), (_, port2, _), m) =
          [ testGroup "Blackbox" $
            concat [ Test.Blackbox.tests port
                   , Test.Blackbox.haTests port2
                   , Test.Blackbox.ssltests $ fmap (\(_,x,_) -> x) m
                   ]
          ]
  
      tests = [ testGroup "Address" Address.tests
              , testGroup "Parser" Parser.tests
  #ifdef HAS_SENDFILE
              , testGroup "SendFile" SendFile.tests
  #endif
              , testGroup "Server" Session.tests
              , testGroup "Socket" Socket.tests
              , testGroup "TimeoutManager" TimeoutManager.tests
              ]
  
  
  ------------------------------------------------------------------------------
  sslPort :: Int -> Maybe Int
  
  #ifdef OPENSSL
  sslPort sp = Just (sp + 100)
  #else
  sslPort _ = Nothing
  #endif
  
  ports :: Int -> (Int, Maybe Int)
  ports sp = (sp, sslPort sp)
  
  
  getStartPort :: IO Int
  getStartPort = (liftM read (getEnv "STARTPORT") >>= E.evaluate)
                   `E.catch` \(_::E.SomeException) -> return 8111
  