module Unison.Codebase.Editor.Output
  ( Output (..),
    AmbiguousReset'Argument (..),
    CreatedProjectBranchFrom (..),
    WhichBranchEmpty (..),
    NumberedOutput (..),
    NumberedArgs,
    ListDetailed,
    HistoryTail (..),
    TestReportStats (..),
    TodoOutput (..),
    todoOutputIsEmpty,
    MoreEntriesThanShown (..),
    UndoFailureReason (..),
    ShareError (..),
    UpdateOrUpgrade (..),
    isFailure,
    isNumberedFailure,
  )
where

import Data.List.NonEmpty (NonEmpty)
import Data.Set qualified as Set
import Data.Set.NonEmpty (NESet)
import Data.Time (UTCTime)
import Network.URI (URI)
import Servant.Client qualified as Servant (ClientError)
import System.Console.Haskeline qualified as Completion
import U.Codebase.Branch.Diff (NameChanges)
import U.Codebase.HashTags (CausalHash)
import U.Codebase.Sqlite.Project qualified as Sqlite
import U.Codebase.Sqlite.ProjectBranch qualified as Sqlite
import U.Codebase.Sqlite.ProjectReflog qualified as ProjectReflog
import Unison.Auth.Types (CredentialFailure)
import Unison.Cli.MergeTypes (MergeSourceAndTarget, MergeSourceOrTarget)
import Unison.Cli.Share.Projects.Types qualified as Share
import Unison.Codebase.Editor.Input
import Unison.Codebase.Editor.Output.BranchDiff (BranchDiffOutput)
import Unison.Codebase.Editor.Output.BranchDiff qualified as BD
import Unison.Codebase.Editor.Output.PushPull (PushPull)
import Unison.Codebase.Editor.RemoteRepo
import Unison.Codebase.Editor.SlurpResult (SlurpResult (..))
import Unison.Codebase.Editor.SlurpResult qualified as SR
import Unison.Codebase.Editor.StructuredArgument (StructuredArgument)
import Unison.Codebase.IntegrityCheck (IntegrityResult (..))
import Unison.Codebase.Path (Path')
import Unison.Codebase.Path qualified as Path
import Unison.Codebase.ProjectPath (Project, ProjectBranch, ProjectPath)
import Unison.Codebase.Runtime qualified as Runtime
import Unison.Codebase.ShortCausalHash (ShortCausalHash)
import Unison.Codebase.ShortCausalHash qualified as SCH
import Unison.CommandLine.BranchRelativePath (BranchRelativePath)
import Unison.CommandLine.InputPattern qualified as Input
import Unison.DataDeclaration qualified as DD
import Unison.DataDeclaration.ConstructorId (ConstructorId)
import Unison.Hash (Hash)
import Unison.HashQualified qualified as HQ
import Unison.HashQualifiedPrime qualified as HQ'
import Unison.LabeledDependency (LabeledDependency)
import Unison.Merge.DeclCoherencyCheck (IncoherentDeclReason, IncoherentDeclReasons (..))
import Unison.Name (Name)
import Unison.NameSegment (NameSegment)
import Unison.Names (Names)
import Unison.Names qualified as Names
import Unison.Names.ResolutionResult qualified as Names
import Unison.NamesWithHistory qualified as Names
import Unison.Parser.Ann (Ann)
import Unison.Prelude
import Unison.PrettyPrintEnv qualified as PPE
import Unison.PrettyPrintEnvDecl (PrettyPrintEnvDecl)
import Unison.PrettyPrintEnvDecl qualified as PPE
import Unison.Project (ProjectAndBranch, ProjectBranchName, ProjectName, Semver)
import Unison.Reference (Reference, TermReference, TermReferenceId, TypeReference)
import Unison.Reference qualified as Reference
import Unison.Referent (Referent)
import Unison.Server.Backend (ShallowListEntry (..))
import Unison.Server.SearchResultPrime (SearchResult')
import Unison.Share.Sync.Types qualified as Sync
import Unison.ShortHash (ShortHash)
import Unison.Symbol (Symbol)
import Unison.Sync.Types qualified as Share (DownloadEntitiesError, UploadEntitiesError)
import Unison.Syntax.Parser qualified as Parser
import Unison.Term (Term)
import Unison.Type (Type)
import Unison.Typechecker.Context qualified as Context
import Unison.UnisonFile qualified as UF
import Unison.Util.Conflicted (Conflicted)
import Unison.Util.Defn (Defn)
import Unison.Util.Defns (DefnsF, defnsAreEmpty)
import Unison.Util.Pretty qualified as P
import Unison.Util.Relation (Relation)
import Unison.WatchKind qualified as WK

type ListDetailed = Bool

type SourceName = Text

-- |
--
--  __NB__: This only temporarily holds `Text`. Until all of the inputs are
--          updated to handle `StructuredArgument`s, we need to ensure that the
--          serialization remains unchanged.
type NumberedArgs = [StructuredArgument]

type HashLength = Int

data NumberedOutput
  = ShowDiffNamespace (Either ShortCausalHash ProjectPath) (Either ShortCausalHash ProjectPath) PPE.PrettyPrintEnv (BranchDiffOutput Symbol Ann)
  | ShowDiffAfterUndo PPE.PrettyPrintEnv (BranchDiffOutput Symbol Ann)
  | ShowDiffAfterDeleteDefinitions PPE.PrettyPrintEnv (BranchDiffOutput Symbol Ann)
  | ShowDiffAfterDeleteBranch Path.Absolute PPE.PrettyPrintEnv (BranchDiffOutput Symbol Ann)
  | ShowDiffAfterModifyBranch Path.Path' Path.Absolute PPE.PrettyPrintEnv (BranchDiffOutput Symbol Ann)
  | ShowDiffAfterMerge
      (Either ProjectPath (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch))
      ProjectPath
      PPE.PrettyPrintEnv
      (BranchDiffOutput Symbol Ann)
  | ShowDiffAfterMergePropagate
      (Either ProjectPath (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch))
      ProjectPath
      Path.Path'
      PPE.PrettyPrintEnv
      (BranchDiffOutput Symbol Ann)
  | ShowDiffAfterMergePreview
      (Either ProjectPath (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch))
      ProjectPath
      PPE.PrettyPrintEnv
      (BranchDiffOutput Symbol Ann)
  | ShowDiffAfterPull Path.Path' Path.Absolute PPE.PrettyPrintEnv (BranchDiffOutput Symbol Ann)
  | -- <authorIdentifier> <authorPath> <relativeBase>
    ShowDiffAfterCreateAuthor NameSegment Path.Path' Path.Absolute PPE.PrettyPrintEnv (BranchDiffOutput Symbol Ann)
  | TestResults
      TestReportStats
      PPE.PrettyPrintEnv
      ShowSuccesses
      ShowFailures
      (Map TermReferenceId [Text]) -- oks
      (Map TermReferenceId [Text]) -- fails
  | Output'Todo !TodoOutput
  | -- | CantDeleteDefinitions ppe couldntDelete becauseTheseStillReferenceThem
    CantDeleteDefinitions PPE.PrettyPrintEnvDecl (Map LabeledDependency (NESet LabeledDependency))
  | -- | CantDeleteNamespace ppe couldntDelete becauseTheseStillReferenceThem
    CantDeleteNamespace PPE.PrettyPrintEnvDecl (Map LabeledDependency (NESet LabeledDependency))
  | -- | DeletedDespiteDependents ppe deletedThings thingsWhichNowHaveUnnamedReferences
    DeletedDespiteDependents PPE.PrettyPrintEnvDecl (Map LabeledDependency (NESet LabeledDependency))
  | -- |    size limit, history                       , how the history ends
    History
      (Maybe Int) -- Amount of history to print
      HashLength
      [(CausalHash, Names.Diff)]
      HistoryTail -- 'origin point' of this view of history.
  | ListProjects [Sqlite.Project]
  | ListBranches ProjectName [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
  | AmbiguousSwitch ProjectName (ProjectAndBranch ProjectName ProjectBranchName)
  | AmbiguousReset AmbiguousReset'Argument (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch, Path.Path) (ProjectAndBranch ProjectName ProjectBranchName)
  | -- | List all direct dependencies which don't have any names in the current branch
    ListNamespaceDependencies
      PPE.PrettyPrintEnv -- PPE containing names for everything from the root namespace.
      ProjectPath -- The namespace we're checking dependencies for.
      (Map LabeledDependency (Set Name)) -- Mapping of external dependencies to their local dependents.
  | ShowProjectBranchReflog
      (Maybe UTCTime {- current time, omitted in transcript tests to be more deterministic -})
      MoreEntriesThanShown
      [ProjectReflog.Entry Project ProjectBranch (CausalHash, SCH.ShortCausalHash)]

data TodoOutput = TodoOutput
  { TodoOutput -> Bool
defnsInLib :: !Bool,
    TodoOutput -> Set TermReferenceId
dependentsOfTodo :: !(Set TermReferenceId),
    TodoOutput -> Defns (Set TermReference) (Set TermReference)
directDependenciesWithoutNames :: !(DefnsF Set TermReference TypeReference),
    TodoOutput -> Int
hashLen :: !Int,
    TodoOutput -> IncoherentDeclReasons
incoherentDeclReasons :: !IncoherentDeclReasons,
    TodoOutput -> Names
nameConflicts :: !Names,
    TodoOutput -> PrettyPrintEnvDecl
ppe :: !PrettyPrintEnvDecl
  }

todoOutputIsEmpty :: TodoOutput -> Bool
todoOutputIsEmpty :: TodoOutput -> Bool
todoOutputIsEmpty TodoOutput
todo =
  Set TermReferenceId -> Bool
forall a. Set a -> Bool
Set.null TodoOutput
todo.dependentsOfTodo
    Bool -> Bool -> Bool
&& Defns (Set TermReference) (Set TermReference) -> Bool
forall (f :: * -> *) (g :: * -> *) a b.
(Foldable f, Foldable g) =>
Defns (f a) (g b) -> Bool
defnsAreEmpty TodoOutput
todo.directDependenciesWithoutNames
    Bool -> Bool -> Bool
&& Names -> Bool
Names.isEmpty TodoOutput
todo.nameConflicts
    Bool -> Bool -> Bool
&& Bool -> Bool
not TodoOutput
todo.defnsInLib
    Bool -> Bool -> Bool
&& TodoOutput
todo.incoherentDeclReasons IncoherentDeclReasons -> IncoherentDeclReasons -> Bool
forall a. Eq a => a -> a -> Bool
== [(Name, Name, Name)]
-> [Name]
-> [(Name, Name)]
-> [(TermReferenceId, Name)]
-> IncoherentDeclReasons
IncoherentDeclReasons [] [] [] []

data AmbiguousReset'Argument
  = AmbiguousReset'Hash
  | AmbiguousReset'Target

--  | ShowDiff

data Output
  = -- Generic Success response; we might consider deleting this.
    Success
  | -- User did `add` or `update` before typechecking a file?
    NoUnisonFile
  | -- Used in Welcome module to instruct user
    PrintMessage (P.Pretty P.ColorText)
  | InvalidSourceName String
  | SourceLoadFailed String
  | -- No main function, the [Type v Ann] are the allowed types
    NoMainFunction (HQ.HashQualified Name) PPE.PrettyPrintEnv [Type Symbol Ann]
  | -- | Function found, but has improper type
    -- Note: the constructor name is misleading here; we weren't necessarily looking for a "main".
    BadMainFunction
      -- | what we were trying to do (e.g. "run", "io.test")
      Text
      -- | name of function
      (HQ.HashQualified Name)
      -- | bad type of function
      (Type Symbol Ann)
      PPE.PrettyPrintEnv
      -- | acceptable type(s) of function
      [Type Symbol Ann]
  | BranchEmpty WhichBranchEmpty
  | LoadPullRequest (ReadRemoteNamespace Void) (ReadRemoteNamespace Void) Path' Path' Path' Path'
  | CreatedNewBranch Path.Absolute
  | BranchAlreadyExists Path'
  | FindNoLocalMatches
  | NoExactTypeMatches
  | TypeAlreadyExists Path.Split' (Set Reference)
  | TypeParseError String (Parser.Err Symbol)
  | ParseResolutionFailures String [Names.ResolutionFailure Ann]
  | TypeHasFreeVars (Type Symbol Ann)
  | TermAlreadyExists Path.Split' (Set Referent)
  | LabeledReferenceAmbiguous Int (HQ.HashQualified Name) (Set LabeledDependency)
  | LabeledReferenceNotFound (HQ.HashQualified Name)
  | DeleteNameAmbiguous Int Path.HQSplit' (Set Referent) (Set Reference)
  | TermAmbiguous PPE.PrettyPrintEnv (HQ.HashQualified Name) (Set Referent)
  | HashAmbiguous ShortHash (Set Referent)
  | BranchHashAmbiguous ShortCausalHash (Set ShortCausalHash)
  | BadNamespace String String
  | BranchNotFound Path'
  | EmptyLooseCodePush Path'
  | EmptyProjectBranchPush (ProjectAndBranch ProjectName ProjectBranchName)
  | NameNotFound Path.HQSplit'
  | NamesNotFound [Name]
  | TypeNotFound Path.HQSplit'
  | TermNotFound Path.HQSplit'
  | MoveNothingFound Path'
  | TypeNotFound' ShortHash
  | TermNotFound' ShortHash
  | NoLastRunResult
  | SaveTermNameConflict Name
  | SearchTermsNotFound [HQ.HashQualified Name]
  | -- Like 'SearchTermsNotFound' but additionally contains term hits
    -- if we are searching for types or type hits if we are searching
    -- for terms. This additional info is used to provide an enhanced
    -- error message.
    SearchTermsNotFoundDetailed
      -- | @True@ if we are searching for a term, @False@ if we are searching for a type
      Bool
      -- | Misses (search terms that returned no hits for terms or types)
      [HQ.HashQualified Name]
      -- | Hits for types if we are searching for terms or terms if we are searching for types
      [HQ.HashQualified Name]
  | -- ask confirmation before deleting the last branch that contains some defns
    -- `Path` is one of the paths the user has requested to delete, and is paired
    -- with whatever named definitions would not have any remaining names if
    -- the path is deleted.
    DeleteBranchConfirmation
      [(Path', (Names, [SearchResult' Symbol Ann]))]
  | DeleteEverythingConfirmation
  | MoveRootBranchConfirmation
  | MovedOverExistingBranch Path'
  | DeletedEverything
  | ListNames
      Int -- hq length to print References
      [(Reference, [HQ'.HashQualified Name])] -- type match, type names
      [(Referent, [HQ'.HashQualified Name])] -- term match, term names
  | GlobalListNames
      (ProjectAndBranch ProjectName ProjectBranchName)
      Int -- hq length to print References
      [(Reference, [HQ'.HashQualified Name])] -- type match, type names
      [(Referent, [HQ'.HashQualified Name])] -- term match, term names
      -- list of all the definitions within this branch
  | ListOfDefinitions FindScope PPE.PrettyPrintEnv ListDetailed [SearchResult' Symbol Ann]
  | ListShallow (IO PPE.PrettyPrintEnv) [ShallowListEntry Symbol Ann]
  | ListStructuredFind [HQ.HashQualified Name]
  | ListTextFind Bool [HQ.HashQualified Name] -- whether lib was included in the search
  | GlobalFindBranchResults (ProjectAndBranch ProjectName ProjectBranchName) PPE.PrettyPrintEnv ListDetailed [SearchResult' Symbol Ann]
  | -- ListStructuredFind patternMatchingUsages termBodyUsages
    -- show the result of add/update
    SlurpOutput Input PPE.PrettyPrintEnv SlurpResult
  | -- Original source, followed by the errors:
    ParseErrors Text [Parser.Err Symbol]
  | TypeErrors Path.Absolute Text PPE.PrettyPrintEnv [Context.ErrorNote Symbol Ann]
  | CompilerBugs Text PPE.PrettyPrintEnv [Context.CompilerBug Symbol Ann]
  | DisplayConflicts (Relation Name Referent) (Relation Name Reference)
  | EvaluationFailure Runtime.Error
  | Evaluated
      SourceFileContents
      PPE.PrettyPrintEnv
      [(Symbol, Term Symbol ())]
      (Map Symbol (Ann, WK.WatchKind, Term Symbol (), Runtime.IsCacheHit))
  | RunResult PPE.PrettyPrintEnv (Term Symbol ())
  | LoadingFile SourceName
  | Typechecked SourceName PPE.PrettyPrintEnv SlurpResult (UF.TypecheckedUnisonFile Symbol Ann)
  | DisplayRendered (Maybe FilePath) (P.Pretty P.ColorText)
  | -- "display" the provided code to the console.
    DisplayDefinitions (P.Pretty P.ColorText)
  | LoadedDefinitionsToSourceFile FilePath Int
  | TestIncrementalOutputStart PPE.PrettyPrintEnv (Int, Int) TermReferenceId
  | TestIncrementalOutputEnd PPE.PrettyPrintEnv (Int, Int) TermReferenceId Bool {- True if success, False for Failure -}
  | CantUndo UndoFailureReason
  | -- new/unrepresented references followed by old/removed
    -- todo: eventually replace these sets with [SearchResult' v Ann]
    -- and a nicer render.
    BustedBuiltins (Set Reference) (Set Reference)
  | ShareError ShareError
  | ViewOnShare (URI, ProjectName, ProjectBranchName)
  | NoConfiguredRemoteMapping PushPull Path.Absolute
  | ConfiguredRemoteMappingParseError PushPull Path.Absolute Text String
  | TermMissingType Reference
  | AboutToPropagatePatch
  | PatchNeedsToBeConflictFree
  | PatchInvolvesExternalDependents PPE.PrettyPrintEnv (Set Reference)
  | StartOfCurrentPathHistory
  | ShowReflog [(Maybe UTCTime, SCH.ShortCausalHash, Text)]
  | PullAlreadyUpToDate
      (ReadRemoteNamespace Share.RemoteProjectBranch)
      (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch)
  | PullSuccessful
      (ReadRemoteNamespace Share.RemoteProjectBranch)
      (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch)
  | AboutToMerge
  | -- | Indicates a trivial merge where the destination was empty and was just replaced.
    MergeOverEmpty (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch)
  | MergeAlreadyUpToDate BranchRelativePath BranchRelativePath
  | -- This will replace the above once `merge.old` is deleted
    MergeAlreadyUpToDate2 !MergeSourceAndTarget
  | PreviewMergeAlreadyUpToDate ProjectPath ProjectPath
  | NotImplemented
  | NoBranchWithHash ShortCausalHash
  | ListDependencies PPE.PrettyPrintEnv (Set LabeledDependency) [HQ.HashQualified Name] [HQ.HashQualified Name] -- types, terms
  | -- | List dependents of a type or term.
    ListDependents PPE.PrettyPrintEnv (Set LabeledDependency) [HQ.HashQualified Name] [HQ.HashQualified Name] -- types, terms
  | DumpNumberedArgs HashLength NumberedArgs
  | DumpBitBooster CausalHash (Map CausalHash [CausalHash])
  | DumpUnisonFileHashes Int [(Name, Reference.Id)] [(Name, Reference.Id)] [(Name, Reference.Id)]
  | BadName Text
  | CouldntLoadBranch CausalHash
  | HelpMessage Input.InputPattern
  | NamespaceEmpty (NonEmpty (Either ShortCausalHash ProjectPath))
  | NoOp
  | -- | @GistCreated repo@ means a causal was just published to @repo@.
    GistCreated (ReadRemoteNamespace Void)
  | -- | Directs the user to URI to begin an authorization flow.
    InitiateAuthFlow URI
  | UnknownCodeServer Text
  | CredentialFailureMsg CredentialFailure
  | PrintVersion Text
  | IntegrityCheck IntegrityResult
  | DisplayDebugNameDiff NameChanges
  | DisplayDebugCompletions [Completion.Completion]
  | DisplayDebugLSPNameCompletions [(Text, Name, LabeledDependency)]
  | DebugDisplayFuzzyOptions Text [String {- arg description, options -}]
  | DebugFuzzyOptionsNoResolver
  | DebugTerm (Bool {- verbose mode -}) (Either (Text {- A builtin hash -}) (Term Symbol Ann))
  | DebugDecl (Either (Text {- A builtin hash -}) (DD.Decl Symbol Ann)) (Maybe ConstructorId {- If 'Just' we're debugging a constructor of the given decl -})
  | AnnotatedFoldRanges Text
  | ClearScreen
  | PulledEmptyBranch (ReadRemoteNamespace Share.RemoteProjectBranch)
  | CreatedProject Bool {- randomly-generated name? -} ProjectName
  | CreatedProjectBranch CreatedProjectBranchFrom (ProjectAndBranch ProjectName ProjectBranchName)
  | CreatedRemoteProject URI (ProjectAndBranch ProjectName ProjectBranchName)
  | CreatedRemoteProjectBranch URI (ProjectAndBranch ProjectName ProjectBranchName)
  | -- We didn't push anything because the remote server is already in the state we want it to be
    RemoteProjectBranchIsUpToDate URI (ProjectAndBranch ProjectName ProjectBranchName)
  | InvalidProjectName Text
  | InvalidProjectBranchName Text
  | InvalidStructuredFindReplace (HQ.HashQualified Name)
  | InvalidStructuredFind (HQ.HashQualified Name)
  | ProjectNameAlreadyExists ProjectName
  | ProjectNameRequiresUserSlug ProjectName -- invariant: this project name doesn't have a user slug :)
  | ProjectAndBranchNameAlreadyExists (ProjectAndBranch ProjectName ProjectBranchName)
  | -- ran a command that only makes sense if on a project branch
    NotOnProjectBranch
  | -- there's no remote project associated with branch, nor any of its parent branches
    NoAssociatedRemoteProject URI (ProjectAndBranch ProjectName ProjectBranchName)
  | -- there's no remote branch associated with branch
    NoAssociatedRemoteProjectBranch URI (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch)
  | LocalProjectDoesntExist ProjectName
  | LocalProjectBranchDoesntExist (ProjectAndBranch ProjectName ProjectBranchName)
  | LocalProjectNorProjectBranchExist ProjectName ProjectBranchName
  | RemoteProjectDoesntExist URI ProjectName
  | RemoteProjectBranchDoesntExist URI (ProjectAndBranch ProjectName ProjectBranchName)
  | RemoteProjectBranchDoesntExist'Push URI (ProjectAndBranch ProjectName ProjectBranchName)
  | RemoteProjectReleaseIsDeprecated URI (ProjectAndBranch ProjectName ProjectBranchName)
  | RemoteProjectPublishedReleaseCannotBeChanged URI (ProjectAndBranch ProjectName ProjectBranchName)
  | -- A remote project branch head wasn't in the expected state
    RemoteProjectBranchHeadMismatch URI (ProjectAndBranch ProjectName ProjectBranchName)
  | Unauthorized Text
  | ServantClientError Servant.ClientError
  | MarkdownOut Text
  | DownloadedEntities Int
  | UploadedEntities Int
  | -- A generic "not implemented" message, for WIP code that's nonetheless been merged into trunk
    NotImplementedYet Text
  | DraftingRelease ProjectBranchName Semver
  | CannotCreateReleaseBranchWithBranchCommand ProjectBranchName Semver
  | CalculatingDiff
  | -- | The `local` in a `clone remote local` is ambiguous
    AmbiguousCloneLocal
      -- | Treating `local` as a project. We may know the branch name, if it was provided in `remote`.
      (ProjectAndBranch ProjectName ProjectBranchName)
      (ProjectAndBranch ProjectName ProjectBranchName)
  | -- | The `remote` in a `clone remote local` is ambiguous
    AmbiguousCloneRemote ProjectName (ProjectAndBranch ProjectName ProjectBranchName)
  | ClonedProjectBranch
      (ProjectAndBranch ProjectName ProjectBranchName)
      (ProjectAndBranch ProjectName ProjectBranchName)
  | RenamedProject ProjectName ProjectName
  | OutputRewrittenFile FilePath ([Symbol {- symbols rewritten -}])
  | RenamedProjectBranch ProjectName ProjectBranchName ProjectBranchName
  | CantRenameBranchTo ProjectBranchName
  | FetchingLatestReleaseOfBase
  | FailedToFetchLatestReleaseOfBase
  | HappyCoding
  | ProjectHasNoReleases ProjectName
  | UpdateLookingForDependents
  | UpdateStartTypechecking
  | UpdateTypecheckingFailure
  | UpdateTypecheckingSuccess
  | UpdateIncompleteConstructorSet UpdateOrUpgrade Name (Map ConstructorId Name) (Maybe Int)
  | UpgradeFailure !ProjectBranchName !ProjectBranchName !FilePath !NameSegment !NameSegment
  | UpgradeSuccess !NameSegment !NameSegment
  | MergeFailure !FilePath !MergeSourceAndTarget !ProjectBranchName
  | MergeSuccess !MergeSourceAndTarget
  | MergeSuccessFastForward !MergeSourceAndTarget
  | MergeConflictedAliases !MergeSourceOrTarget !(Defn (Name, Name) (Name, Name))
  | MergeConflictInvolvingBuiltin !(Defn Name Name)
  | MergeDefnsInLib !MergeSourceOrTarget
  | InstalledLibdep !(ProjectAndBranch ProjectName ProjectBranchName) !NameSegment
  | NoUpgradeInProgress
  | UseLibInstallNotPull !(ProjectAndBranch ProjectName ProjectBranchName)
  | PullIntoMissingBranch !(ReadRemoteNamespace Share.RemoteProjectBranch) !(ProjectAndBranch (Maybe ProjectName) ProjectBranchName)
  | NoMergeInProgress
  | Output'DebugSynhashTerm !TermReference !Hash !Text
  | ConflictedDefn !Text {- what operation? -} !(Defn (Conflicted Name Referent) (Conflicted Name TypeReference))
  | IncoherentDeclDuringMerge !MergeSourceOrTarget !IncoherentDeclReason
  | IncoherentDeclDuringUpdate !IncoherentDeclReason

data MoreEntriesThanShown = MoreEntriesThanShown | AllEntriesShown
  deriving (MoreEntriesThanShown -> MoreEntriesThanShown -> Bool
(MoreEntriesThanShown -> MoreEntriesThanShown -> Bool)
-> (MoreEntriesThanShown -> MoreEntriesThanShown -> Bool)
-> Eq MoreEntriesThanShown
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MoreEntriesThanShown -> MoreEntriesThanShown -> Bool
== :: MoreEntriesThanShown -> MoreEntriesThanShown -> Bool
$c/= :: MoreEntriesThanShown -> MoreEntriesThanShown -> Bool
/= :: MoreEntriesThanShown -> MoreEntriesThanShown -> Bool
Eq, Int -> MoreEntriesThanShown -> ShowS
[MoreEntriesThanShown] -> ShowS
MoreEntriesThanShown -> String
(Int -> MoreEntriesThanShown -> ShowS)
-> (MoreEntriesThanShown -> String)
-> ([MoreEntriesThanShown] -> ShowS)
-> Show MoreEntriesThanShown
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MoreEntriesThanShown -> ShowS
showsPrec :: Int -> MoreEntriesThanShown -> ShowS
$cshow :: MoreEntriesThanShown -> String
show :: MoreEntriesThanShown -> String
$cshowList :: [MoreEntriesThanShown] -> ShowS
showList :: [MoreEntriesThanShown] -> ShowS
Show)

data UpdateOrUpgrade = UOUUpdate | UOUUpgrade

-- | What did we create a project branch from?
--
--   * Loose code
--   * Nothingness (we made an empty branch)
--   * Other branch (in another project)
--   * Parent branch (in this project)
data CreatedProjectBranchFrom
  = CreatedProjectBranchFrom'LooseCode Path.Absolute
  | CreatedProjectBranchFrom'Nothingness
  | CreatedProjectBranchFrom'OtherBranch (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch)
  | CreatedProjectBranchFrom'ParentBranch ProjectBranchName

-- | A branch was empty. But how do we refer to that branch?
data WhichBranchEmpty
  = WhichBranchEmptyHash ShortCausalHash
  | WhichBranchEmptyPath ProjectPath

data ShareError
  = ShareErrorDownloadEntities Share.DownloadEntitiesError
  | ShareErrorGetCausalHashByPath Sync.GetCausalHashByPathError
  | ShareErrorPull Sync.PullError
  | ShareErrorTransport Sync.CodeserverTransportError
  | ShareErrorUploadEntities Share.UploadEntitiesError
  | ShareExpectedSquashedHead

data HistoryTail
  = EndOfLog CausalHash
  | MergeTail CausalHash [CausalHash]
  | PageEnd CausalHash Int -- PageEnd nextHash nextIndex
  deriving (Int -> HistoryTail -> ShowS
[HistoryTail] -> ShowS
HistoryTail -> String
(Int -> HistoryTail -> ShowS)
-> (HistoryTail -> String)
-> ([HistoryTail] -> ShowS)
-> Show HistoryTail
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HistoryTail -> ShowS
showsPrec :: Int -> HistoryTail -> ShowS
$cshow :: HistoryTail -> String
show :: HistoryTail -> String
$cshowList :: [HistoryTail] -> ShowS
showList :: [HistoryTail] -> ShowS
Show)

data TestReportStats
  = CachedTests TotalCount CachedCount
  | NewlyComputed
  deriving (Int -> TestReportStats -> ShowS
[TestReportStats] -> ShowS
TestReportStats -> String
(Int -> TestReportStats -> ShowS)
-> (TestReportStats -> String)
-> ([TestReportStats] -> ShowS)
-> Show TestReportStats
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TestReportStats -> ShowS
showsPrec :: Int -> TestReportStats -> ShowS
$cshow :: TestReportStats -> String
show :: TestReportStats -> String
$cshowList :: [TestReportStats] -> ShowS
showList :: [TestReportStats] -> ShowS
Show)

type TotalCount = Int -- total number of tests

type CachedCount = Int -- number of tests found in the cache

type ShowSuccesses = Bool -- whether to list results or just summarize

type ShowFailures = Bool -- whether to list results or just summarize

data UndoFailureReason = CantUndoPastStart | CantUndoPastMerge deriving (Int -> UndoFailureReason -> ShowS
[UndoFailureReason] -> ShowS
UndoFailureReason -> String
(Int -> UndoFailureReason -> ShowS)
-> (UndoFailureReason -> String)
-> ([UndoFailureReason] -> ShowS)
-> Show UndoFailureReason
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UndoFailureReason -> ShowS
showsPrec :: Int -> UndoFailureReason -> ShowS
$cshow :: UndoFailureReason -> String
show :: UndoFailureReason -> String
$cshowList :: [UndoFailureReason] -> ShowS
showList :: [UndoFailureReason] -> ShowS
Show)

type SourceFileContents = Text

isFailure :: Output -> Bool
isFailure :: Output -> Bool
isFailure Output
o = case Output
o of
  Output
UpdateLookingForDependents -> Bool
False
  Output
UpdateStartTypechecking -> Bool
False
  UpdateTypecheckingFailure {} -> Bool
True
  UpdateTypecheckingSuccess {} -> Bool
False
  UpdateIncompleteConstructorSet {} -> Bool
True
  AmbiguousCloneLocal {} -> Bool
True
  AmbiguousCloneRemote {} -> Bool
True
  ClonedProjectBranch {} -> Bool
False
  NoLastRunResult {} -> Bool
True
  SaveTermNameConflict {} -> Bool
True
  RunResult {} -> Bool
False
  Success {} -> Bool
False
  PrintMessage {} -> Bool
False
  CouldntLoadBranch {} -> Bool
True
  NoUnisonFile {} -> Bool
True
  InvalidSourceName {} -> Bool
True
  SourceLoadFailed {} -> Bool
True
  NoMainFunction {} -> Bool
True
  BadMainFunction {} -> Bool
True
  CreatedNewBranch {} -> Bool
False
  BranchAlreadyExists {} -> Bool
True
  -- we do a global search after finding no local matches, so let's not call this a failure yet
  FindNoLocalMatches {} -> Bool
False
  Output
NoExactTypeMatches -> Bool
True
  BranchEmpty {} -> Bool
True
  EmptyLooseCodePush {} -> Bool
True
  EmptyProjectBranchPush {} -> Bool
True
  TypeAlreadyExists {} -> Bool
True
  TypeParseError {} -> Bool
True
  ParseResolutionFailures {} -> Bool
True
  TypeHasFreeVars {} -> Bool
True
  TermAlreadyExists {} -> Bool
True
  LabeledReferenceAmbiguous {} -> Bool
True
  LabeledReferenceNotFound {} -> Bool
True
  DeleteNameAmbiguous {} -> Bool
True
  TermAmbiguous {} -> Bool
True
  BranchHashAmbiguous {} -> Bool
True
  BadName {} -> Bool
True
  BadNamespace {} -> Bool
True
  BranchNotFound {} -> Bool
True
  NameNotFound {} -> Bool
True
  NamesNotFound [Name]
_ -> Bool
True
  TypeNotFound {} -> Bool
True
  TypeNotFound' {} -> Bool
True
  TermNotFound {} -> Bool
True
  MoveNothingFound {} -> Bool
True
  TermNotFound' {} -> Bool
True
  SearchTermsNotFound [HashQualified Name]
ts -> Bool -> Bool
not ([HashQualified Name] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [HashQualified Name]
ts)
  SearchTermsNotFoundDetailed Bool
_ [HashQualified Name]
misses [HashQualified Name]
otherHits -> Bool -> Bool
not ([HashQualified Name] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [HashQualified Name]
misses Bool -> Bool -> Bool
&& [HashQualified Name] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [HashQualified Name]
otherHits)
  DeleteBranchConfirmation {} -> Bool
False
  Output
DeleteEverythingConfirmation -> Bool
False
  Output
MoveRootBranchConfirmation -> Bool
False
  MovedOverExistingBranch {} -> Bool
False
  Output
DeletedEverything -> Bool
False
  ListNames Int
_ [(TermReference, [HashQualified Name])]
tys [(Referent, [HashQualified Name])]
tms -> [(Referent, [HashQualified Name])] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Referent, [HashQualified Name])]
tms Bool -> Bool -> Bool
&& [(TermReference, [HashQualified Name])] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(TermReference, [HashQualified Name])]
tys
  GlobalListNames {} -> Bool
False
  ListOfDefinitions FindScope
_ PrettyPrintEnv
_ Bool
_ [SearchResult' Symbol Ann]
ds -> [SearchResult' Symbol Ann] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SearchResult' Symbol Ann]
ds
  GlobalFindBranchResults ProjectAndBranch ProjectName ProjectBranchName
_ PrettyPrintEnv
_ Bool
_ [SearchResult' Symbol Ann]
_ -> Bool
False
  ListStructuredFind [HashQualified Name]
tms -> [HashQualified Name] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [HashQualified Name]
tms
  ListTextFind Bool
_ [HashQualified Name]
tms -> [HashQualified Name] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [HashQualified Name]
tms
  SlurpOutput Input
_ PrettyPrintEnv
_ SlurpResult
sr -> Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ SlurpResult -> Bool
SR.isOk SlurpResult
sr
  ParseErrors {} -> Bool
True
  TypeErrors {} -> Bool
True
  CompilerBugs {} -> Bool
True
  DisplayConflicts {} -> Bool
False
  EvaluationFailure {} -> Bool
True
  Evaluated {} -> Bool
False
  LoadingFile {} -> Bool
False
  Typechecked {} -> Bool
False
  LoadedDefinitionsToSourceFile {} -> Bool
False
  DisplayDefinitions {} -> Bool
False
  DisplayRendered {} -> Bool
False
  TestIncrementalOutputStart {} -> Bool
False
  TestIncrementalOutputEnd {} -> Bool
False
  CantUndo {} -> Bool
True
  BustedBuiltins {} -> Bool
True
  NoConfiguredRemoteMapping {} -> Bool
True
  ConfiguredRemoteMappingParseError {} -> Bool
True
  PatchNeedsToBeConflictFree {} -> Bool
True
  PatchInvolvesExternalDependents {} -> Bool
True
  AboutToPropagatePatch {} -> Bool
False
  Output
StartOfCurrentPathHistory -> Bool
True
  Output
NotImplemented -> Bool
True
  DumpNumberedArgs {} -> Bool
False
  DumpBitBooster {} -> Bool
False
  NoBranchWithHash {} -> Bool
True
  PullAlreadyUpToDate {} -> Bool
False
  PullSuccessful {} -> Bool
False
  AboutToMerge {} -> Bool
False
  MergeOverEmpty {} -> Bool
False
  MergeAlreadyUpToDate {} -> Bool
False
  MergeAlreadyUpToDate2 {} -> Bool
False
  PreviewMergeAlreadyUpToDate {} -> Bool
False
  ListShallow IO PrettyPrintEnv
_ [ShallowListEntry Symbol Ann]
es -> [ShallowListEntry Symbol Ann] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ShallowListEntry Symbol Ann]
es
  HashAmbiguous {} -> Bool
True
  ShowReflog {} -> Bool
False
  LoadPullRequest {} -> Bool
False
  HelpMessage {} -> Bool
True
  Output
NoOp -> Bool
False
  ListDependencies {} -> Bool
False
  ListDependents {} -> Bool
False
  TermMissingType {} -> Bool
True
  DumpUnisonFileHashes Int
_ [(Name, TermReferenceId)]
x [(Name, TermReferenceId)]
y [(Name, TermReferenceId)]
z -> [(Name, TermReferenceId)]
x [(Name, TermReferenceId)] -> [(Name, TermReferenceId)] -> Bool
forall a. Eq a => a -> a -> Bool
== [(Name, TermReferenceId)]
forall a. Monoid a => a
mempty Bool -> Bool -> Bool
&& [(Name, TermReferenceId)]
y [(Name, TermReferenceId)] -> [(Name, TermReferenceId)] -> Bool
forall a. Eq a => a -> a -> Bool
== [(Name, TermReferenceId)]
forall a. Monoid a => a
mempty Bool -> Bool -> Bool
&& [(Name, TermReferenceId)]
z [(Name, TermReferenceId)] -> [(Name, TermReferenceId)] -> Bool
forall a. Eq a => a -> a -> Bool
== [(Name, TermReferenceId)]
forall a. Monoid a => a
mempty
  NamespaceEmpty {} -> Bool
True
  GistCreated {} -> Bool
False
  InitiateAuthFlow {} -> Bool
False
  UnknownCodeServer {} -> Bool
True
  CredentialFailureMsg {} -> Bool
True
  PrintVersion {} -> Bool
False
  IntegrityCheck IntegrityResult
r ->
    case IntegrityResult
r of
      IntegrityResult
NoIntegrityErrors -> Bool
False
      IntegrityErrorDetected {} -> Bool
True
  ShareError {} -> Bool
True
  ViewOnShare {} -> Bool
False
  DisplayDebugCompletions {} -> Bool
False
  DisplayDebugLSPNameCompletions {} -> Bool
False
  DebugDisplayFuzzyOptions {} -> Bool
False
  DebugFuzzyOptionsNoResolver {} -> Bool
True
  DebugTerm {} -> Bool
False
  DebugDecl {} -> Bool
False
  AnnotatedFoldRanges {} -> Bool
False
  DisplayDebugNameDiff {} -> Bool
False
  Output
ClearScreen -> Bool
False
  PulledEmptyBranch {} -> Bool
False
  CreatedProject {} -> Bool
False
  CreatedProjectBranch {} -> Bool
False
  CreatedRemoteProject {} -> Bool
False
  CreatedRemoteProjectBranch {} -> Bool
False
  InvalidProjectName {} -> Bool
True
  InvalidProjectBranchName {} -> Bool
True
  InvalidStructuredFindReplace {} -> Bool
True
  InvalidStructuredFind {} -> Bool
True
  ProjectNameAlreadyExists {} -> Bool
True
  ProjectNameRequiresUserSlug {} -> Bool
True
  NotOnProjectBranch {} -> Bool
True
  NoAssociatedRemoteProject {} -> Bool
True
  NoAssociatedRemoteProjectBranch {} -> Bool
True
  ProjectAndBranchNameAlreadyExists {} -> Bool
True
  LocalProjectDoesntExist {} -> Bool
True
  LocalProjectBranchDoesntExist {} -> Bool
True
  LocalProjectNorProjectBranchExist {} -> Bool
True
  RemoteProjectDoesntExist {} -> Bool
True
  RemoteProjectBranchDoesntExist {} -> Bool
True
  RemoteProjectBranchDoesntExist'Push {} -> Bool
True
  RemoteProjectReleaseIsDeprecated {} -> Bool
True
  RemoteProjectPublishedReleaseCannotBeChanged {} -> Bool
True
  RemoteProjectBranchHeadMismatch {} -> Bool
True
  Unauthorized {} -> Bool
True
  ServantClientError {} -> Bool
True
  MarkdownOut {} -> Bool
False
  NotImplementedYet {} -> Bool
True
  RemoteProjectBranchIsUpToDate {} -> Bool
False
  DownloadedEntities {} -> Bool
False
  UploadedEntities {} -> Bool
False
  DraftingRelease {} -> Bool
False
  CannotCreateReleaseBranchWithBranchCommand {} -> Bool
True
  CalculatingDiff {} -> Bool
False
  RenamedProject {} -> Bool
False
  OutputRewrittenFile {} -> Bool
False
  RenamedProjectBranch {} -> Bool
False
  CantRenameBranchTo {} -> Bool
True
  FetchingLatestReleaseOfBase {} -> Bool
False
  FailedToFetchLatestReleaseOfBase {} -> Bool
True
  HappyCoding {} -> Bool
False
  ProjectHasNoReleases {} -> Bool
True
  UpgradeFailure {} -> Bool
True
  UpgradeSuccess {} -> Bool
False
  MergeFailure {} -> Bool
True
  MergeSuccess {} -> Bool
False
  MergeSuccessFastForward {} -> Bool
False
  MergeConflictedAliases {} -> Bool
True
  MergeConflictInvolvingBuiltin {} -> Bool
True
  MergeDefnsInLib {} -> Bool
True
  InstalledLibdep {} -> Bool
False
  NoUpgradeInProgress {} -> Bool
True
  UseLibInstallNotPull {} -> Bool
False
  PullIntoMissingBranch {} -> Bool
True
  NoMergeInProgress {} -> Bool
True
  Output'DebugSynhashTerm {} -> Bool
False
  ConflictedDefn {} -> Bool
True
  IncoherentDeclDuringMerge {} -> Bool
True
  IncoherentDeclDuringUpdate {} -> Bool
True

isNumberedFailure :: NumberedOutput -> Bool
isNumberedFailure :: NumberedOutput -> Bool
isNumberedFailure = \case
  AmbiguousReset {} -> Bool
True
  AmbiguousSwitch {} -> Bool
True
  CantDeleteDefinitions {} -> Bool
True
  CantDeleteNamespace {} -> Bool
True
  DeletedDespiteDependents {} -> Bool
False
  History {} -> Bool
False
  ListBranches {} -> Bool
False
  ListProjects {} -> Bool
False
  ShowDiffAfterCreateAuthor {} -> Bool
False
  ShowDiffAfterDeleteBranch {} -> Bool
False
  ShowDiffAfterDeleteDefinitions {} -> Bool
False
  ShowDiffAfterMerge {} -> Bool
False
  ShowDiffAfterMergePreview {} -> Bool
False
  ShowDiffAfterMergePropagate {} -> Bool
False
  ShowDiffAfterModifyBranch {} -> Bool
False
  ShowDiffAfterPull {} -> Bool
False
  ShowDiffAfterUndo {} -> Bool
False
  ShowDiffNamespace Either ShortCausalHash ProjectPath
_ Either ShortCausalHash ProjectPath
_ PrettyPrintEnv
_ BranchDiffOutput Symbol Ann
bd -> BranchDiffOutput Symbol Ann -> Bool
forall v a. BranchDiffOutput v a -> Bool
BD.isEmpty BranchDiffOutput Symbol Ann
bd
  ListNamespaceDependencies {} -> Bool
False
  TestResults TestReportStats
_ PrettyPrintEnv
_ Bool
_ Bool
_ Map TermReferenceId [Text]
_ Map TermReferenceId [Text]
fails -> Bool -> Bool
not (Map TermReferenceId [Text] -> Bool
forall a. Map TermReferenceId a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Map TermReferenceId [Text]
fails)
  Output'Todo {} -> Bool
False
  ShowProjectBranchReflog {} -> Bool
False