{-# OPTIONS_GHC -Wall -Werror #-}

{-# LANGUAGE NoGeneralizedNewtypeDeriving #-}
{-# LANGUAGE Safe                         #-}

--------------------------------------------------------------------------------

-- |
-- Copyright  : (c) 2026 SPISE MISU ApS
-- License    : SSPL-1.0 OR AGPL-3.0-only
-- Maintainer : SPISE MISU <mail+hackage@spisemisu.com>
-- Stability  : experimental

--------------------------------------------------------------------------------

module Agent.IO.Effects
  ( -- * LLM (Config)
    LlmConf(llmPathCWD)
    -- * LLM (Chat)
  , LlmChatConf(llmChatKey, llmChatAPI)
  , LlmChatPost(llmChatWeb)
  , -- * LLM (Code)
    LlmCodeRoot(llmCodeDir)
  , LlmCodeMask(llmCodeMsk)
  , LlmCodeTmpl(llmCodeIns, llmCodeExa)
  , LlmCodeRead(llmCodeSeq, llmCodeGet, llmCodeGit)
  , LlmCodeSave(llmCodePut)
  , LlmCodeConf(llmCodeKey, llmCodeAPI)
  , LlmCodePost(llmCodeWeb)
  , -- * LLM (Plan)
    LlmPlanRoot(llmPlanDir)
  , LlmPlanMask(llmPlanMsk)
  , LlmPlanRead(llmPlanSeq, llmPlanGet)
  , LlmPlanConf(llmPlanKey, llmPlanAPI)
  , LlmPlanPost(llmPlanWeb)
  )
where

--------------------------------------------------------------------------------

import qualified Internal.LLM as LLM

--------------------------------------------------------------------------------

class
  Monad m
  => LlmConf m
  where
    llmPathCWD
      :: m (Maybe LLM.Root)

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

class
  Monad m
  => LlmChatConf m
  where
    llmChatAPI
      :: m (Maybe String)
    llmChatKey
      :: m (Maybe String)

--------------------------------------------------------------------------------

class
  LlmChatConf m
  => LlmChatPost m
  where
    llmChatWeb
      :: String
      -> m (Either String String)

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

class
  Monad m
  => LlmCodeRoot m
  where
    llmCodeDir
      :: m String -- Ex: "src"

--------------------------------------------------------------------------------

class
  Monad m
  => LlmCodeMask m
  where
    llmCodeMsk
      :: m [ String ] -- Ex: [ "*.hs", "*.lhs" ]

--------------------------------------------------------------------------------

class
  Monad m
  => LlmCodeTmpl m
  where
    llmCodeIns
      :: m [LLM.File]
    llmCodeExa
      :: m [LLM.File]

--------------------------------------------------------------------------------

class
  ( LlmConf m
  , LlmCodeRoot m
  , LlmCodeMask m
  )
  => LlmCodeRead m
  where
    llmCodeSeq
      :: Maybe LLM.Filter
      -> m (Either [String] LLM.FilePaths)
    llmCodeGet
      :: LLM.AbsoluteFilePath
      -> m (Either String LLM.File)
    llmCodeGit
      :: m (Either String String)

--------------------------------------------------------------------------------

class
  ( LlmConf m
  , LlmCodeRoot m
  )
  => LlmCodeSave m
  where
    llmCodePut
      :: String
      -> LLM.Files
      -> m (Either String String)

--------------------------------------------------------------------------------

class
  Monad m
  => LlmCodeConf m
  where
    llmCodeAPI
      :: m (Maybe String)
    llmCodeKey
      :: m (Maybe String)

--------------------------------------------------------------------------------

class
  LlmCodeConf m
  => LlmCodePost m
  where
    llmCodeWeb
      :: String
      -> m (Either String String)

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

class
  Monad m
  => LlmPlanRoot m
  where
    llmPlanDir
      :: m String -- Ex: "llm"

--------------------------------------------------------------------------------

class
  Monad m
  => LlmPlanMask m
  where
    llmPlanMsk
      :: m [ String ] -- Ex: [ "plan_*.md" ]

--------------------------------------------------------------------------------

class
  ( LlmConf m
  , LlmPlanRoot m
  , LlmPlanMask m
  , LlmCodeRead m
  )
  => LlmPlanRead m
  where
    llmPlanSeq
      :: Maybe LLM.Filter
      -> m (Either [String] LLM.FilePaths)
    llmPlanGet
      :: String
      -> m (Either String LLM.File)

--------------------------------------------------------------------------------

class
  Monad m
  => LlmPlanConf m
  where
    llmPlanAPI
      :: m (Maybe String)
    llmPlanKey
      :: m (Maybe String)

--------------------------------------------------------------------------------

class
  ( LlmConf m
  , LlmPlanConf m
  )
  => LlmPlanPost m
  where
    llmPlanWeb
      :: String
      -> m (Either String String)

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------