// Copyright (c) 2025 TerraByte Inc.
//
// This script serves as the clean, public-facing API for all Git operations.
// It creates promises and delegates the actual implementation work to the
// internal GitExecutors class.

using Terra.Arbitrator.Promises;
using Terra.Arbitrator.Settings;
using System.Collections.Generic;

namespace Terra.Arbitrator.Services
{
    /// <summary>
    /// The public static API for interacting with the Git repository.
    /// </summary>
    public static class GitService
    {
        /// <summary>
        /// Synchronously gets the Git status for a single file.
        /// Required by UI elements that cannot easily use promises.
        /// </summary>
        public static GitChange GetChangeForFile(string filePath)
        {
            return GitExecutors.GetChangeForFile(filePath);
        }
        
        /// <summary>
        /// Compares the local repository state to the tracked remote branch.
        /// </summary>
        public static IPromise<List<GitChange>> CompareLocalToRemote()
        {
            return new Promise<List<GitChange>>(GitExecutors.GetLocalStatusExecutor);
        }
        
        /// <summary>
        /// Commits and pushes the selected files to the remote repository.
        /// </summary>
        public static IPromise<string> CommitAndPush(List<GitChange> changesToCommit, string commitMessage, string username, string email)
        {
            return new Promise<string>((resolve, reject) => 
                GitExecutors.CommitAndPushExecutor(resolve, reject, changesToCommit, commitMessage, username, email));
        }
        
        /// <summary>
        /// Reverts all local changes for a single file.
        /// </summary>
        public static IPromise<string> ResetFileChanges(GitChange changeToReset)
        {
            return new Promise<string>((resolve, reject) => 
                GitExecutors.ResetFileExecutor(resolve, reject, changeToReset));
        }

        /// <summary>
        /// Launches an external diff tool to compare file versions.
        /// </summary>
        public static IPromise<string> LaunchExternalDiff(GitChange change)
        {
            return new Promise<string>((resolve, reject) => GitExecutors.LaunchExternalDiffExecutor(resolve, reject, change));
        }
        
        /// <summary>
        /// Analyzes if a pull operation results in conflicts.
        /// </summary>
        public static IPromise<PullAnalysisResult> AnalyzePullConflicts()
        {
            return new Promise<PullAnalysisResult>(GitExecutors.FileLevelConflictCheckExecutor);
        }

        /// <summary>
        /// Performs a "safe" pull, assuming no conflicts will occur.
        /// </summary>
        public static IPromise<string> PerformSafePull()
        {
            return new Promise<string>(GitExecutors.SafePullExecutor);
        }

        /// <summary>
        /// Performs a pull that may result in merge conflicts.
        /// </summary>
        public static IPromise<string> ForcePull()
        {
            return new Promise<string>(GitExecutors.ForcePullExecutor);
        }
        
        /// <summary>
        /// Launches an external merge tool for a conflicted file.
        /// </summary>
        public static IPromise<string> LaunchMergeTool(GitChange change)
        {
            return new Promise<string>((resolve, reject) => GitExecutors.LaunchMergeToolExecutor(resolve, reject, change));
        }

        /// <summary>
        /// Unstages all files if the repository is in a clean, non-conflicted state.
        /// </summary>
        public static IPromise<bool> UnstageAllFilesIfSafe()
        {
            return new Promise<bool>(GitExecutors.UnstageAllFilesIfSafeExecutor);
        }
        
        /// <summary>
        /// Discards all local changes (tracked and untracked) in the repository.
        /// </summary>
        public static IPromise<string> ResetAllChanges()
        {
            return new Promise<string>(GitExecutors.ResetAllChangesExecutor);
        }
    }
}