content: {-# LANGUAGE OverloadedStrings   #-}
  {-# LANGUAGE ScopedTypeVariables #-}
  
  module MCP.Server.Transport.Stdio
    ( -- * STDIO Transport
      transportRunStdio
    ) where
  
  import           Control.Monad          (when)
  import           Control.Monad.IO.Class (MonadIO, liftIO)
  import           Data.Aeson
  import qualified Data.ByteString.Lazy   as BSL
  import qualified Data.Text              as T
  import qualified Data.Text.Encoding     as TE
  import qualified Data.Text.IO           as TIO
  import           System.IO              (hFlush, hPutStrLn, stderr, stdout)
  
  import           MCP.Server.Handlers
  import           MCP.Server.JsonRpc
  import           MCP.Server.Types
  
  
  -- | Transport-specific implementation for STDIO
  import           System.IO              (hSetEncoding, utf8)
  
  transportRunStdio :: (MonadIO m) => McpServerInfo -> McpServerHandlers m -> m ()
  transportRunStdio serverInfo handlers = do
    -- Ensure UTF-8 encoding for all handles
    liftIO $ do
      hSetEncoding stderr utf8
      hSetEncoding stdout utf8
    loop
    where
      loop = do
        input <- liftIO TIO.getLine
        when (not $ T.null $ T.strip input) $ do
          -- Use TIO.hPutStrLn for UTF-8 output
          liftIO $ TIO.hPutStrLn stderr $ "Received request: " <> input
          case eitherDecode (BSL.fromStrict $ TE.encodeUtf8 input) of
            Left err -> liftIO $ TIO.hPutStrLn stderr $ "Parse error: " <> T.pack err
            Right jsonValue -> do
              case parseJsonRpcMessage jsonValue of
                Left err -> liftIO $ TIO.hPutStrLn stderr $ "JSON-RPC parse error: " <> T.pack err
                Right message -> do
                  liftIO $ TIO.hPutStrLn stderr $ "Processing message: " <> T.pack (show (getMessageSummary message))
                  response <- handleMcpMessage serverInfo handlers message
                  case response of
                    Just responseMsg -> do
                      liftIO $ TIO.hPutStrLn stderr $ "Sending response for: " <> T.pack (show (getMessageSummary message))
                      let responseText = TE.decodeUtf8 $ BSL.toStrict $ encode $ encodeJsonRpcMessage responseMsg
                      liftIO $ TIO.putStrLn responseText
                      liftIO $ hFlush stdout
                    Nothing -> liftIO $ TIO.hPutStrLn stderr $ "No response needed for: " <> T.pack (show (getMessageSummary message))
          loop
  
  