-- | @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
  pp <- Cli ProjectPath
Cli.getCurrentProjectPath
  (project, branches) <-
    Cli.runTransactionWithRollback \forall void. Output -> Transaction void
rollback -> do
      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)
      branches <- Queries.loadAllProjectBranchInfo (project ^. #projectId)
      pure (project, branches)
  Cli.respondNumbered (Output.ListBranches (project ^. #name) (f 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