eyre
  :: forall e
   . (HasPierEnv e)
  => e
  -> Ship
  -> (EvErr -> STM ())
  -> Bool
  -> (Text -> RIO e ())
  -> KingSubsite
  -> ([Ev], RAcquire e (HttpServerEf -> IO ()))
eyre env who plan isFake stderr sub = (initialEvents, runHttpServer)
 where
  king = fromIntegral (env ^. kingIdL)
  multi = env ^. multiEyreApiL

  initialEvents :: [Ev]
  initialEvents = [bornEv king]

  runHttpServer :: RAcquire e (HttpServerEf -> IO ())
  runHttpServer = handleEf <$> mkRAcquire
    (Drv <$> newMVar Nothing)
    (\(Drv v) -> stopService v kill >>= fromEither)

  kill :: HasLogFunc e => Serv -> RIO e ()
  kill Serv{..} = do
    atomically (leaveMultiEyre multi who)
    io (saKil sLop)
    io (saKil sIns)
    io $ for_ sSec (\sec -> (saKil sec))
    io (removePortsFile sPortsFile)

  restart :: Drv -> HttpServerConf -> RIO e Serv
  restart (Drv var) conf = do
    logInfo "Restarting http server"
    let onFatal = runRIO env $ do
          -- XX instead maybe restart following logic under HSESetConfig below
          stderr "A web server problem has occurred. Please restart your ship."
          view killKingActionL >>= atomically
    let startAct = startServ who isFake conf plan stderr onFatal sub
    res <- fromEither =<< restartService var startAct kill
    logInfo "Done restating http server"
    pure res

  liveFailed _ = pure ()

  handleEf :: Drv -> HttpServerEf -> IO ()
  handleEf drv = runRIO env . \case
    HSESetConfig (i, ()) conf -> do
      logInfo (displayShow ("EYRE", "%set-config"))
      Serv {..} <- restart drv conf
      logInfo (displayShow ("EYRE", "%set-config", "Sending %live"))
      atomically $ plan (EvErr (liveEv sServId sPorts) liveFailed)
      logInfo "Write ports file"
      io (writePortsFile sPortsFile sPorts)
    HSEResponse (i, req, _seq, ()) ev -> do
      logDebug (displayShow ("EYRE", "%response"))
      execRespActs drv who (fromIntegral req) ev
eyre
  :: forall e
   . (HasPierEnv e)
  => e
  -> Ship
  -> (EvErr -> STM ())
  -> Bool
  -> (Text -> RIO e ())
  -> KingSubsite
  -> ([Ev], RAcquire e (HttpServerEf -> IO ()))
eyre env who plan isFake stderr sub = (initialEvents, runHttpServer)
 where
  king = fromIntegral (env ^. kingIdL)
  multi = env ^. multiEyreApiL

  initialEvents :: [Ev]
  initialEvents = [bornEv king]

  runHttpServer :: RAcquire e (HttpServerEf -> IO ())
  runHttpServer = handleEf <$> mkRAcquire
    (Drv <$> newMVar Nothing)
    (\(Drv v) -> stopService v kill >>= fromEither)

  kill :: HasLogFunc e => Serv -> RIO e ()
  kill Serv{..} = do
    atomically (leaveMultiEyre multi who)
    io (saKil sLop)
    io (saKil sIns)
    io $ for_ sSec (\sec -> (saKil sec))
    io (removePortsFile sPortsFile)

  restart :: Drv -> HttpServerConf -> RIO e Serv
  restart (Drv var) conf = do
    logInfo "Restarting http server"
    let onFatal = runRIO env $ do
          -- XX instead maybe restart following logic under HSESetConfig below
          stderr "A web server problem has occurred. Please restart your ship."
          view killKingActionL >>= atomically
    let startAct = startServ who isFake conf plan stderr onFatal sub
    res <- fromEither =<< restartService var startAct kill
    logInfo "Done restating http server"
    pure res

  liveFailed _ = pure ()

  handleEf :: Drv -> HttpServerEf -> IO ()
  handleEf drv = runRIO env . \case
    HSESetConfig (i, ()) conf -> do
      logInfo (displayShow ("EYRE", "%set-config"))
      Serv {..} <- restart drv conf
      logInfo (displayShow ("EYRE", "%set-config", "Sending %live"))
      atomically $ plan (EvErr (liveEv sServId sPorts) liveFailed)
      logInfo "Write ports file"
      io (writePortsFile sPortsFile sPorts)
    HSEResponse (i, req, _seq, ()) ev -> do
      logDebug (displayShow ("EYRE", "%response"))
      execRespActs drv who (fromIntegral req) ev
eyre env who plan isFake stderr sub = (initialEvents, runHttpServer)
 where
  king = fromIntegral (env ^. kingIdL)
  multi = env ^. multiEyreApiL

  initialEvents :: [Ev]
  initialEvents = [bornEv king]

  runHttpServer :: RAcquire e (HttpServerEf -> IO ())
  runHttpServer = handleEf <$> mkRAcquire
    (Drv <$> newMVar Nothing)
    (\(Drv v) -> stopService v kill >>= fromEither)

  kill :: HasLogFunc e => Serv -> RIO e ()
  kill Serv{..} = do
    atomically (leaveMultiEyre multi who)
    io (saKil sLop)
    io (saKil sIns)
    io $ for_ sSec (\sec -> (saKil sec))
    io (removePortsFile sPortsFile)

  restart :: Drv -> HttpServerConf -> RIO e Serv
  restart (Drv var) conf = do
    logInfo "Restarting http server"
    let onFatal = runRIO env $ do
          -- XX instead maybe restart following logic under HSESetConfig below
          stderr "A web server problem has occurred. Please restart your ship."
          view killKingActionL >>= atomically
    let startAct = startServ who isFake conf plan stderr onFatal sub
    res <- fromEither =<< restartService var startAct kill
    logInfo "Done restating http server"
    pure res

  liveFailed _ = pure ()

  handleEf :: Drv -> HttpServerEf -> IO ()
  handleEf drv = runRIO env . \case
    HSESetConfig (i, ()) conf -> do
      logInfo (displayShow ("EYRE", "%set-config"))
      Serv {..} <- restart drv conf
      logInfo (displayShow ("EYRE", "%set-config", "Sending %live"))
      atomically $ plan (EvErr (liveEv sServId sPorts) liveFailed)
      logInfo "Write ports file"
      io (writePortsFile sPortsFile sPorts)
    HSEResponse (i, req, _seq, ()) ev -> do
      logDebug (displayShow ("EYRE", "%response"))
      execRespActs drv who (fromIntegral req) ev