content: {-# LANGUAGE CPP #-}
  --{-# LANGUAGE MultilineStrings #-}
  
  module Main where
  
  import System.IO
  import System.Exit
  import Options.Applicative
  import qualified Control.Exception.Safe as E
  import Paths_pty_mcp_server (version)
  import Data.Version (showVersion)
  
  import qualified PMS.Application.Service.App.Control as A
  import qualified PMS.Application.Service.DM.Type as A
  import qualified PMS.UI.Request.App.Control as URQ
  import qualified PMS.UI.Response.App.Control as URS
  import qualified PMS.UI.Notification.App.Control as UNO
  import qualified PMS.Infra.CmdRun.App.Control as ICR
  import qualified PMS.Infra.ProcSpawn.App.Control as IPS
  import qualified PMS.Infra.Serial.App.Control as SER
  import qualified PMS.Infra.Socket.App.Control as SCK
  import qualified PMS.Infra.Watch.App.Control as IWA
  import qualified PMS.Domain.Service.App.Control as DSR
  
  #ifdef mingw32_HOST_OS
  #else
  import qualified PMS.Infrastructure.App.Control as INF
  #endif
  
  -- |
  --
  main :: IO ()
  main = getArgs >>= \args -> do
  #ifdef mingw32_HOST_OS
    let apps = [URQ.run, URS.run, UNO.run, ICR.run, IPS.run, IWA.run, DSR.run, SCK.run, SER.run]
  #else
    let apps = [URQ.run, URS.run, UNO.run, ICR.run, IPS.run, IWA.run, DSR.run, SCK.run, SER.run, INF.run]
  #endif
    flip E.catchAny exception
       $ flip E.finally finalize
         $ A.run args apps
  
    where
      finalize = do
        hPutStrLn stderr "-----------------------------------------------------------------------------"
        hPutStrLn stderr "Finalize called."
        hPutStrLn stderr "-----------------------------------------------------------------------------"
  
      exception e = do
        hPutStrLn stderr "-----------------------------------------------------------------------------"
        hPutStrLn stderr "ERROR exit."
        hPutStrLn stderr $ show e
        hPutStrLn stderr "-----------------------------------------------------------------------------"
        exitFailure
  
  -------------------------------------------------------------------------------
  -- |
  --   optparse-applicative
  --
  getArgs :: IO A.ArgData
  getArgs = execParser parseInfo
  
  -- |
  --
  parseInfo :: ParserInfo A.ArgData
  parseInfo = info (helper <*> verOpt <*> options) $ mconcat
    [ fullDesc
    , header   "pty-mcp-server - Pseudo-terminal MCP Server"
    , footer   "Copyright (c) 2025 phoityne. All rights reserved."
    , progDesc "A minimal PTY-based server for running shell commands in MCP style.\n Designed for AI to control interactive programs like GHCi or bash."
    ]
  
  -- |
  --
  verOpt :: Parser (a -> a)
  verOpt = infoOption msg $ mconcat
    [ short 'v'
    , long  "version"
    , help  "Show version"
    ]
    where
      msg = "pty-mcp-server-" ++ showVersion version
  
  
  -- |
  --
  options :: Parser A.ArgData
  options = (<*>) helper
    $ A.ArgData
    <$> confOption
  
  -- |
  --
  confOption :: Parser (Maybe FilePath)
  confOption = optional $ strOption $ mconcat
    [ short 'y', long "yaml"
    , help "config file"
    , metavar "FILE"
    ]
  