-- | @branches@ input handler
module Unison.Codebase.Editor.HandleInput.Branches
  ( handleBranches,
  )
where

import Control.Lens (mapped, _2)
import Data.Map.Strict qualified as Map
import Network.URI (URI)
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.Prelude
import Unison.Project (ProjectBranchName, ProjectName)

handleBranches :: Maybe ProjectName -> Cli ()
handleBranches :: Maybe ProjectName -> Cli ()
handleBranches Maybe ProjectName
maybeProjectName = do
  ProjectPath
pp <- Cli ProjectPath
Cli.getCurrentProjectPath
  (Project
project, Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
branches) <-
    ((forall void. Output -> Transaction void)
 -> Transaction
      (Project,
       Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))))
-> Cli
     (Project,
      Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName)))
forall a.
((forall void. Output -> Transaction void) -> Transaction a)
-> Cli a
Cli.runTransactionWithRollback \forall void. Output -> Transaction void
rollback -> do
      Project
project <-
        case Maybe ProjectName
maybeProjectName of
          Just ProjectName
projectName -> do
            ProjectName -> Transaction (Maybe Project)
Queries.loadProjectByName ProjectName
projectName Transaction (Maybe Project)
-> (Transaction (Maybe Project) -> Transaction Project)
-> Transaction Project
forall a b. a -> (a -> b) -> b
& Transaction Project
-> Transaction (Maybe Project) -> Transaction Project
forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
onNothingM do
              Output -> Transaction Project
forall void. Output -> Transaction void
rollback (ProjectName -> Output
Output.LocalProjectDoesntExist ProjectName
projectName)
          Maybe ProjectName
Nothing -> do
            Project -> Transaction Project
forall a. a -> Transaction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ProjectPath
pp ProjectPath -> Getting Project ProjectPath Project -> Project
forall s a. s -> Getting a s a -> a
^. Getting Project ProjectPath Project
#project)
      Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
branches <- ProjectId
-> Transaction
     (Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName)))
Queries.loadAllProjectBranchInfo (Project
project Project -> Getting ProjectId Project ProjectId -> ProjectId
forall s a. s -> Getting a s a -> a
^. Getting ProjectId Project ProjectId
#projectId)
      pure (Project
project, Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
branches)
  NumberedOutput -> Cli ()
Cli.respondNumbered (ProjectName
-> [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
-> NumberedOutput
Output.ListBranches (Project
project Project -> Getting ProjectName Project ProjectName -> ProjectName
forall s a. s -> Getting a s a -> a
^. Getting ProjectName Project ProjectName
#name) (Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
-> [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
f Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
branches))
  where
    f ::
      Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName)) ->
      [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
    f :: Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
-> [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
f =
      ASetter
  [(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))]
  [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
  (Map URI (ProjectName, ProjectBranchName))
  [(URI, ProjectName, ProjectBranchName)]
-> (Map URI (ProjectName, ProjectBranchName)
    -> [(URI, ProjectName, ProjectBranchName)])
-> [(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))]
-> [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (((ProjectBranchName, Map URI (ProjectName, ProjectBranchName))
 -> Identity
      (ProjectBranchName, [(URI, ProjectName, ProjectBranchName)]))
-> [(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))]
-> Identity
     [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
Setter
  [(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))]
  [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
  (ProjectBranchName, Map URI (ProjectName, ProjectBranchName))
  (ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped (((ProjectBranchName, Map URI (ProjectName, ProjectBranchName))
  -> Identity
       (ProjectBranchName, [(URI, ProjectName, ProjectBranchName)]))
 -> [(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))]
 -> Identity
      [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])])
-> ((Map URI (ProjectName, ProjectBranchName)
     -> Identity [(URI, ProjectName, ProjectBranchName)])
    -> (ProjectBranchName, Map URI (ProjectName, ProjectBranchName))
    -> Identity
         (ProjectBranchName, [(URI, ProjectName, ProjectBranchName)]))
-> ASetter
     [(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))]
     [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
     (Map URI (ProjectName, ProjectBranchName))
     [(URI, ProjectName, ProjectBranchName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map URI (ProjectName, ProjectBranchName)
 -> Identity [(URI, ProjectName, ProjectBranchName)])
-> (ProjectBranchName, Map URI (ProjectName, ProjectBranchName))
-> Identity
     (ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])
forall s t a b. Field2 s t a b => Lens s t a b
Lens
  (ProjectBranchName, Map URI (ProjectName, ProjectBranchName))
  (ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])
  (Map URI (ProjectName, ProjectBranchName))
  [(URI, ProjectName, ProjectBranchName)]
_2) (((URI, (ProjectName, ProjectBranchName))
 -> (URI, ProjectName, ProjectBranchName))
-> [(URI, (ProjectName, ProjectBranchName))]
-> [(URI, ProjectName, ProjectBranchName)]
forall a b. (a -> b) -> [a] -> [b]
map (\(URI
h, (ProjectName
p, ProjectBranchName
b)) -> (URI
h, ProjectName
p, ProjectBranchName
b)) ([(URI, (ProjectName, ProjectBranchName))]
 -> [(URI, ProjectName, ProjectBranchName)])
-> (Map URI (ProjectName, ProjectBranchName)
    -> [(URI, (ProjectName, ProjectBranchName))])
-> Map URI (ProjectName, ProjectBranchName)
-> [(URI, ProjectName, ProjectBranchName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map URI (ProjectName, ProjectBranchName)
-> [(URI, (ProjectName, ProjectBranchName))]
forall k a. Map k a -> [(k, a)]
Map.toList) ([(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))]
 -> [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])])
-> (Map
      ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
    -> [(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))])
-> Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
-> [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map ProjectBranchName (Map URI (ProjectName, ProjectBranchName))
-> [(ProjectBranchName, Map URI (ProjectName, ProjectBranchName))]
forall k a. Map k a -> [(k, a)]
Map.toList