{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}

module Data.Ollama.Copy
  ( -- * Copy Model API
    copyModel
  ) where

import Control.Monad (when)
import Data.Aeson
import Data.Ollama.Common.Utils qualified as CU
import Data.Text (Text)
import Data.Text qualified as T
import GHC.Generics
import Network.HTTP.Client
import Network.HTTP.Types.Status (status404)

-- TODO: Add Options parameter
-- TODO: Add Context parameter
data CopyModelOps = CopyModelOps
  { CopyModelOps -> Text
source :: Text
  , CopyModelOps -> Text
destination :: Text
  }
  deriving (Int -> CopyModelOps -> ShowS
[CopyModelOps] -> ShowS
CopyModelOps -> String
(Int -> CopyModelOps -> ShowS)
-> (CopyModelOps -> String)
-> ([CopyModelOps] -> ShowS)
-> Show CopyModelOps
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CopyModelOps -> ShowS
showsPrec :: Int -> CopyModelOps -> ShowS
$cshow :: CopyModelOps -> String
show :: CopyModelOps -> String
$cshowList :: [CopyModelOps] -> ShowS
showList :: [CopyModelOps] -> ShowS
Show, CopyModelOps -> CopyModelOps -> Bool
(CopyModelOps -> CopyModelOps -> Bool)
-> (CopyModelOps -> CopyModelOps -> Bool) -> Eq CopyModelOps
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CopyModelOps -> CopyModelOps -> Bool
== :: CopyModelOps -> CopyModelOps -> Bool
$c/= :: CopyModelOps -> CopyModelOps -> Bool
/= :: CopyModelOps -> CopyModelOps -> Bool
Eq, (forall x. CopyModelOps -> Rep CopyModelOps x)
-> (forall x. Rep CopyModelOps x -> CopyModelOps)
-> Generic CopyModelOps
forall x. Rep CopyModelOps x -> CopyModelOps
forall x. CopyModelOps -> Rep CopyModelOps x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CopyModelOps -> Rep CopyModelOps x
from :: forall x. CopyModelOps -> Rep CopyModelOps x
$cto :: forall x. Rep CopyModelOps x -> CopyModelOps
to :: forall x. Rep CopyModelOps x -> CopyModelOps
Generic, [CopyModelOps] -> Value
[CopyModelOps] -> Encoding
CopyModelOps -> Bool
CopyModelOps -> Value
CopyModelOps -> Encoding
(CopyModelOps -> Value)
-> (CopyModelOps -> Encoding)
-> ([CopyModelOps] -> Value)
-> ([CopyModelOps] -> Encoding)
-> (CopyModelOps -> Bool)
-> ToJSON CopyModelOps
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: CopyModelOps -> Value
toJSON :: CopyModelOps -> Value
$ctoEncoding :: CopyModelOps -> Encoding
toEncoding :: CopyModelOps -> Encoding
$ctoJSONList :: [CopyModelOps] -> Value
toJSONList :: [CopyModelOps] -> Value
$ctoEncodingList :: [CopyModelOps] -> Encoding
toEncodingList :: [CopyModelOps] -> Encoding
$comitField :: CopyModelOps -> Bool
omitField :: CopyModelOps -> Bool
ToJSON)

-- | Copy model from source to destination
copyModel ::
  -- | Source model
  Text ->
  -- | Destination model
  Text ->
  IO ()
copyModel :: Text -> Text -> IO ()
copyModel
  Text
source
  Text
destination =
    do
      let url :: Text
url = OllamaClient -> Text
CU.host OllamaClient
CU.defaultOllama
      Manager
manager <- ManagerSettings -> IO Manager
newManager ManagerSettings
defaultManagerSettings
      Request
initialRequest <- String -> IO Request
forall (m :: * -> *). MonadThrow m => String -> m Request
parseRequest (String -> IO Request) -> String -> IO Request
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack (Text
url Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/api/copy")
      let reqBody :: CopyModelOps
reqBody =
            CopyModelOps
              { $sel:source:CopyModelOps :: Text
source = Text
source
              , $sel:destination:CopyModelOps :: Text
destination = Text
destination
              }
          request :: Request
request =
            Request
initialRequest
              { method = "POST"
              , requestBody = RequestBodyLBS $ encode reqBody
              }
      Response ByteString
response <- Request -> Manager -> IO (Response ByteString)
httpLbs Request
request Manager
manager
      Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when
        (Response ByteString -> Status
forall body. Response body -> Status
responseStatus Response ByteString
response Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
== Status
status404)
        (String -> IO ()
putStrLn String
"Source Model does not exist")