content: {-# LANGUAGE OverloadedStrings #-}
  
  -- | Running your app inside GHCi.
  --
  -- > stack ghci
  --
  -- To start your app, run:
  --
  -- > :l DevelMain
  -- > DevelMain.update
  --
  -- You can also call @DevelMain.shutdown@ to stop the app
  --
  -- There is more information about this approach,
  -- on the wiki: https://github.com/yesodweb/yesod/wiki/ghci
  
  module DevelMain where
  
  import           Prelude
  
  import           Control.Concurrent       (MVar, ThreadId, forkIO, killThread,
                                             newEmptyMVar, putMVar, takeMVar)
  import           Control.Exception        (finally)
  import           Control.Monad            ((>=>))
  import           Data.IORef               (IORef, newIORef, readIORef,
                                             writeIORef)
  import           Foreign.Store            (Store (..), lookupStore, readStore,
                                             storeAction, withStore)
  import           GHC.Word                 (Word32)
  import           Network.Wai.Handler.Warp (defaultSettings, runSettings,
                                             setPort)
  
  -- import           OddJobs.Endpoints                     (startApp, stopApp)
  -- import qualified ElmCodeGen
  
  -- | Start or restart the server.
  -- newStore is from foreign-store.
  -- A Store holds onto some data across ghci reloads
  update :: IO ()
  update = undefined
  -- update = do
  --     mtidStore <- lookupStore tidStoreNum
  --     case mtidStore of
  --       -- no server running
  --       Nothing -> do
  --           done <- storeAction doneStore newEmptyMVar
  --           tid <- start done
  --           _ <- storeAction (Store tidStoreNum) (newIORef tid)
  --           return ()
  --       -- server is already running
  --       Just tidStore -> restartAppInNewThread tidStore
  --   where
  --     doneStore :: Store (MVar ())
  --     doneStore = Store 0
  
  --     -- shut the server down with killThread and wait for the done signal
  --     restartAppInNewThread :: Store (IORef ThreadId) -> IO ()
  --     restartAppInNewThread tidStore = modifyStoredIORef tidStore $ \tid -> do
  --         killThread tid
  --         withStore doneStore takeMVar
  --         readStore doneStore >>= start
  
  
  --     -- | Start the server in a separate thread.
  --     start :: MVar () -- ^ Written to when the thread is killed.
  --           -> IO ThreadId
  --     start done = do
  --         -- (port, config, app) <- initialize
  --         -- ElmCodeGen.updatea
  --         forkIO (finally startApp
  --                         -- Note that this implies concurrency
  --                         -- between shutdownApp and the next app that is starting.
  --                         -- Normally this should be fine
  --                         (putMVar done () >> stopApp))
  
  -- | kill the server
  shutdown :: IO ()
  shutdown = do
      mtidStore <- lookupStore tidStoreNum
      case mtidStore of
        -- no server running
        Nothing -> putStrLn "no app running"
        Just tidStore -> do
            withStore tidStore $ readIORef >=> killThread
            putStrLn "App is shutdown"
  
  tidStoreNum :: Word32
  tidStoreNum = 1
  
  modifyStoredIORef :: Store (IORef a) -> (a -> IO a) -> IO ()
  modifyStoredIORef store f = withStore store $ \ref -> do
      v <- readIORef ref
      f v >>= writeIORef ref
  
  main :: IO ()
  main = update
  