-- | @branch.rename@ input handler
module Unison.Codebase.Editor.HandleInput.BranchRename
  ( handleBranchRename,
  )
where

import U.Codebase.Sqlite.Queries qualified as Queries
import Unison.Cli.Monad (Cli)
import Unison.Cli.Monad qualified as Cli
import Unison.Cli.MonadUtils qualified as Cli
import Unison.Codebase.Editor.Output qualified as Output
import Unison.Codebase.ProjectPath qualified as PP
import Unison.Prelude
import Unison.Project (ProjectAndBranch (..), ProjectBranchName, ProjectBranchNameKind (..), classifyProjectBranchName)

handleBranchRename :: ProjectBranchName -> Cli ()
handleBranchRename :: ProjectBranchName -> Cli ()
handleBranchRename ProjectBranchName
newBranchName = do
  PP.ProjectPath Project
project ProjectBranch
branch Absolute
_path <- Cli (ProjectPathG Project ProjectBranch)
Cli.getCurrentProjectPath

  case ProjectBranchName -> ProjectBranchNameKind
classifyProjectBranchName ProjectBranchName
newBranchName of
    ProjectBranchNameKind'Contributor {} -> () -> Cli ()
forall a. a -> Cli a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    ProjectBranchNameKind'DraftRelease {} -> () -> Cli ()
forall a. a -> Cli a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    ProjectBranchNameKind'NothingSpecial {} -> () -> Cli ()
forall a. a -> Cli a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    ProjectBranchNameKind'Release {} -> Output -> Cli ()
forall a. Output -> Cli a
Cli.returnEarly (ProjectBranchName -> Output
Output.CantRenameBranchTo ProjectBranchName
newBranchName)

  let projectName :: ProjectName
projectName = Project
project Project -> Getting ProjectName Project ProjectName -> ProjectName
forall s a. s -> Getting a s a -> a
^. Getting ProjectName Project ProjectName
#name
  let oldBranchName :: ProjectBranchName
oldBranchName = ProjectBranch
branch ProjectBranch
-> Getting ProjectBranchName ProjectBranch ProjectBranchName
-> ProjectBranchName
forall s a. s -> Getting a s a -> a
^. Getting ProjectBranchName ProjectBranch ProjectBranchName
#name
  Bool -> Cli () -> Cli ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ProjectBranchName
oldBranchName ProjectBranchName -> ProjectBranchName -> Bool
forall a. Eq a => a -> a -> Bool
/= ProjectBranchName
newBranchName) do
    ((forall void. Output -> Transaction void) -> Transaction ())
-> Cli ()
forall a.
((forall void. Output -> Transaction void) -> Transaction a)
-> Cli a
Cli.runTransactionWithRollback \forall void. Output -> Transaction void
rollback -> do
      ProjectId -> ProjectBranchName -> Transaction (Maybe ProjectBranch)
Queries.loadProjectBranchByName (Project
project Project -> Getting ProjectId Project ProjectId -> ProjectId
forall s a. s -> Getting a s a -> a
^. Getting ProjectId Project ProjectId
#projectId) ProjectBranchName
newBranchName Transaction (Maybe ProjectBranch)
-> (Maybe ProjectBranch -> Transaction ()) -> Transaction ()
forall a b. Transaction a -> (a -> Transaction b) -> Transaction b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Just ProjectBranch
_ -> Output -> Transaction ()
forall void. Output -> Transaction void
rollback (ProjectAndBranch ProjectName ProjectBranchName -> Output
Output.ProjectAndBranchNameAlreadyExists (ProjectName
-> ProjectBranchName
-> ProjectAndBranch ProjectName ProjectBranchName
forall a b. a -> b -> ProjectAndBranch a b
ProjectAndBranch ProjectName
projectName ProjectBranchName
newBranchName))
        Maybe ProjectBranch
Nothing -> ProjectId -> ProjectBranchId -> ProjectBranchName -> Transaction ()
Queries.renameProjectBranch (Project
project Project -> Getting ProjectId Project ProjectId -> ProjectId
forall s a. s -> Getting a s a -> a
^. Getting ProjectId Project ProjectId
#projectId) (ProjectBranch
branch ProjectBranch
-> Getting ProjectBranchId ProjectBranch ProjectBranchId
-> ProjectBranchId
forall s a. s -> Getting a s a -> a
^. Getting ProjectBranchId ProjectBranch ProjectBranchId
#branchId) ProjectBranchName
newBranchName
  Output -> Cli ()
Cli.respond (ProjectName -> ProjectBranchName -> ProjectBranchName -> Output
Output.RenamedProjectBranch ProjectName
projectName ProjectBranchName
oldBranchName ProjectBranchName
newBranchName)