module Unison.Codebase.Editor.HandleInput.MoveType (doMoveType, moveTypeSteps) where

import Data.Set qualified as Set
import Unison.Cli.Monad (Cli)
import Unison.Cli.Monad qualified as Cli
import Unison.Cli.MonadUtils qualified as Cli
import Unison.Codebase qualified as Codebase
import Unison.Codebase.Branch (Branch0)
import Unison.Codebase.BranchUtil qualified as BranchUtil
import Unison.Codebase.Editor.Output qualified as Output
import Unison.Codebase.Path (Path')
import Unison.Codebase.Path qualified as Path
import Unison.Codebase.ProjectPath qualified as PP
import Unison.HashQualifiedPrime qualified as HQ'
import Unison.Prelude

moveTypeSteps ::
  HQ'.HashQualified (Path.Split Path') -> Path.Split Path' -> Cli [(Path.Absolute, Branch0 m -> Branch0 m)]
moveTypeSteps :: forall (m :: * -> *).
HashQualified (Split Path')
-> Split Path' -> Cli [(Absolute, Branch0 m -> Branch0 m)]
moveTypeSteps HashQualified (Split Path')
src' Split Path'
dest' = do
  src <- (Split Path' -> Cli (Split (ProjectPathG Project ProjectBranch)))
-> HashQualified (Split Path')
-> Cli (HashQualified (Split (ProjectPathG Project ProjectBranch)))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HashQualified a -> f (HashQualified b)
traverse Split Path' -> Cli (Split (ProjectPathG Project ProjectBranch))
Cli.resolveSplit' HashQualified (Split Path')
src'
  srcTypes <- Cli.getTypesAt src
  case Set.toList srcTypes of
    [] -> [(Absolute, Branch0 m -> Branch0 m)]
-> Cli [(Absolute, Branch0 m -> Branch0 m)]
forall a. a -> Cli a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
    TypeReference
_ : TypeReference
_ : [TypeReference]
_ -> do
      hqLength <- Transaction Int -> Cli Int
forall a. Transaction a -> Cli a
Cli.runTransaction Transaction Int
Codebase.hashLength
      Cli.returnEarly (Output.DeleteNameAmbiguous hqLength src' Set.empty srcTypes)
    [TypeReference
srcType] -> do
      dest <- Split Path' -> Cli (Split (ProjectPathG Project ProjectBranch))
Cli.resolveSplit' Split Path'
dest'
      destTypes <- Cli.getTypesAt $ HQ'.NameOnly dest
      when (not (Set.null destTypes)) do
        Cli.returnEarly (Output.TypeAlreadyExists dest' destTypes)
      pure
        [ -- Mitchell: throwing away any hash-qualification here seems wrong!
          BranchUtil.makeDeleteTypeName (first (view PP.absPath_) $ HQ'.toName src) srcType,
          BranchUtil.makeAddTypeName (first (view PP.absPath_) dest) srcType
        ]

doMoveType :: HQ'.HashQualified (Path.Split Path') -> Path.Split Path' -> Text -> Cli ()
doMoveType :: HashQualified (Split Path') -> Split Path' -> Text -> Cli ()
doMoveType HashQualified (Split Path')
src' Split Path'
dest' Text
description = do
  steps <- HashQualified (Split Path')
-> Split Path' -> Cli [(Absolute, Branch0 IO -> Branch0 IO)]
forall (m :: * -> *).
HashQualified (Split Path')
-> Split Path' -> Cli [(Absolute, Branch0 m -> Branch0 m)]
moveTypeSteps HashQualified (Split Path')
src' Split Path'
dest'
  when (null steps) do
    Cli.returnEarly (Output.TypeNotFound src')
  pb <- Cli.getCurrentProjectBranch
  Cli.stepManyAt pb description steps
  Cli.respond Output.Success