using MarketAlly.AIPlugin; using LibGit2Sharp; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace MarketAlly.AIPlugin.Refactoring.Plugins { public class GitConfiguration { public string AuthorName { get; set; } = "MarketAlly Refactoring Tool"; public string AuthorEmail { get; set; } = "refactor@localhost"; } // Corrected Git integration manager with proper LibGit2Sharp API usage public class GitRefactoringManager { private readonly string _repositoryPath; private readonly GitConfiguration _gitConfig; public bool IsGitRepository { get; private set; } public GitRefactoringManager(string repositoryPath, GitConfiguration gitConfig = null) { _repositoryPath = repositoryPath; _gitConfig = gitConfig ?? new GitConfiguration(); IsGitRepository = Repository.IsValid(repositoryPath); } public async Task CreateRefactoringBranch(string branchName, bool applyChanges) { if (!IsGitRepository) return null; var gitInfo = new GitRefactoringInfo { RepositoryPath = _repositoryPath, NewBranchName = branchName, CreatedAt = DateTime.UtcNow }; try { using (var repo = new Repository(_repositoryPath)) { gitInfo.OriginalBranch = repo.Head.FriendlyName; gitInfo.OriginalCommit = repo.Head.Tip.Sha; // Check if working directory is clean var status = repo.RetrieveStatus(); if (status.IsDirty) { gitInfo.Success = false; gitInfo.Error = "Working directory has uncommitted changes. Please commit or stash changes before refactoring."; return gitInfo; } if (applyChanges) { // Check if branch already exists var existingBranch = repo.Branches[branchName]; if (existingBranch != null) { // Generate unique branch name var timestamp = DateTime.Now.ToString("HHmmss"); branchName = $"{branchName}-{timestamp}"; gitInfo.NewBranchName = branchName; } // Create and checkout new branch using Commands.Checkout var newBranch = repo.CreateBranch(branchName); Commands.Checkout(repo, newBranch); gitInfo.BranchCreated = true; } gitInfo.Success = true; } } catch (Exception ex) { gitInfo.Success = false; gitInfo.Error = ex.Message; } return await Task.FromResult(gitInfo); } public async Task CommitChanges(string message, List operationsPerformed) { if (!IsGitRepository) return false; try { using (var repo = new Repository(_repositoryPath)) { // Get repository status var status = repo.RetrieveStatus(); if (!status.IsDirty) { Console.WriteLine("No changes to commit."); return await Task.FromResult(false); } // Stage all modified files foreach (var modified in status.Modified) { repo.Index.Add(modified.FilePath); } // Stage all new files foreach (var untracked in status.Untracked) { repo.Index.Add(untracked.FilePath); } // Stage all renamed files foreach (var renamed in status.RenamedInIndex) { repo.Index.Add(renamed.FilePath); } // Write the index changes repo.Index.Write(); // Create commit if there are staged changes var indexStatus = repo.RetrieveStatus(); if (indexStatus.Added.Any() || indexStatus.Modified.Any() || indexStatus.Staged.Any()) { var signature = new Signature(_gitConfig.AuthorName, _gitConfig.AuthorEmail, DateTimeOffset.Now); // Enhanced commit message with operation details var enhancedMessage = $"{message}\n\nOperations performed:\n{string.Join("\n", operationsPerformed.Select(op => $"- {op}"))}"; var commit = repo.Commit(enhancedMessage, signature, signature); Console.WriteLine($"Created commit: {commit.Sha[..8]} - {message}"); return await Task.FromResult(true); } return await Task.FromResult(false); } } catch (Exception ex) { Console.WriteLine($"Git commit failed: {ex.Message}"); return await Task.FromResult(false); } } public async Task GetRepositoryStatus() { if (!IsGitRepository) return null; try { using (var repo = new Repository(_repositoryPath)) { var status = repo.RetrieveStatus(); return await Task.FromResult(new GitStatusInfo { IsClean = !status.IsDirty, CurrentBranch = repo.Head.FriendlyName, LatestCommitSha = repo.Head.Tip.Sha, LatestCommitMessage = repo.Head.Tip.MessageShort, LatestCommitAuthor = repo.Head.Tip.Author.Name, LatestCommitDate = repo.Head.Tip.Author.When, ModifiedFiles = status.Modified.Select(f => f.FilePath).ToList(), AddedFiles = status.Added.Select(f => f.FilePath).ToList(), DeletedFiles = status.Removed.Select(f => f.FilePath).ToList(), UntrackedFiles = status.Untracked.Select(f => f.FilePath).ToList(), StagedFiles = status.Staged.Select(f => f.FilePath).ToList() }); } } catch (Exception ex) { return new GitStatusInfo { IsClean = false, Error = ex.Message }; } } public async Task SwitchToBranch(string branchName) { if (!IsGitRepository) return false; try { using (var repo = new Repository(_repositoryPath)) { var branch = repo.Branches[branchName]; if (branch == null) { Console.WriteLine($"Branch '{branchName}' not found."); return false; } Commands.Checkout(repo, branch); Console.WriteLine($"Switched to branch '{branchName}'"); return await Task.FromResult(true); } } catch (Exception ex) { Console.WriteLine($"Failed to switch to branch '{branchName}': {ex.Message}"); return await Task.FromResult(false); } } public async Task DeleteBranch(string branchName, bool force = false) { if (!IsGitRepository) return false; try { using (var repo = new Repository(_repositoryPath)) { var branch = repo.Branches[branchName]; if (branch == null) { Console.WriteLine($"Branch '{branchName}' not found."); return false; } if (branch.IsCurrentRepositoryHead) { Console.WriteLine($"Cannot delete current branch '{branchName}'. Switch to another branch first."); return false; } repo.Branches.Remove(branch); Console.WriteLine($"Deleted branch '{branchName}'"); return await Task.FromResult(true); } } catch (Exception ex) { Console.WriteLine($"Failed to delete branch '{branchName}': {ex.Message}"); return await Task.FromResult(false); } } public async Task> GetBranches() { if (!IsGitRepository) return new List(); try { using (var repo = new Repository(_repositoryPath)) { return await Task.FromResult(repo.Branches.Select(b => b.FriendlyName).ToList()); } } catch (Exception ex) { Console.WriteLine($"Failed to get branches: {ex.Message}"); return new List(); } } public async Task HasUncommittedChanges() { if (!IsGitRepository) return false; try { using (var repo = new Repository(_repositoryPath)) { var status = repo.RetrieveStatus(); return await Task.FromResult(status.IsDirty); } } catch (Exception ex) { Console.WriteLine($"Failed to check repository status: {ex.Message}"); return false; } } public async Task GetCurrentBranch() { if (!IsGitRepository) return "Not a Git repository"; try { using (var repo = new Repository(_repositoryPath)) { return await Task.FromResult(repo.Head.FriendlyName); } } catch (Exception ex) { return $"Error: {ex.Message}"; } } } // Enhanced Git status information public class GitStatusInfo { public bool IsClean { get; set; } public string CurrentBranch { get; set; } = string.Empty; public string LatestCommitSha { get; set; } = string.Empty; public string LatestCommitMessage { get; set; } = string.Empty; public string LatestCommitAuthor { get; set; } = string.Empty; public DateTimeOffset LatestCommitDate { get; set; } public List ModifiedFiles { get; set; } = new List(); public List AddedFiles { get; set; } = new List(); public List DeletedFiles { get; set; } = new List(); public List UntrackedFiles { get; set; } = new List(); public List StagedFiles { get; set; } = new List(); public string Error { get; set; } = string.Empty; } // Enhanced commands for the solution plugin public static class GitCommands { public static List GenerateReviewCommands(GitRefactoringInfo gitInfo) { var commands = new List(); if (gitInfo?.NewBranchName != null) { commands.Add("# Review the refactoring changes:"); commands.Add($"git log --oneline -5 # See recent commits"); commands.Add($"git diff {gitInfo.OriginalBranch}..{gitInfo.NewBranchName} --stat # See file changes summary"); commands.Add($"git diff {gitInfo.OriginalBranch}..{gitInfo.NewBranchName} # See detailed changes"); commands.Add(""); } return commands; } public static List GenerateMergeCommands(GitRefactoringInfo gitInfo) { var commands = new List(); if (gitInfo?.NewBranchName != null && gitInfo?.OriginalBranch != null) { commands.Add("# To merge the refactoring back to main:"); commands.Add($"git checkout {gitInfo.OriginalBranch}"); commands.Add($"git merge {gitInfo.NewBranchName}"); commands.Add($"git branch -d {gitInfo.NewBranchName} # Delete the refactor branch"); commands.Add(""); } return commands; } public static List GenerateRollbackCommands(GitRefactoringInfo gitInfo) { var commands = new List(); if (gitInfo?.NewBranchName != null && gitInfo?.OriginalBranch != null) { commands.Add("# To discard all refactoring changes:"); commands.Add($"git checkout {gitInfo.OriginalBranch}"); commands.Add($"git branch -D {gitInfo.NewBranchName} # Force delete the refactor branch"); commands.Add("# Your original code is completely restored!"); commands.Add(""); } return commands; } public static List GenerateCommitCommands(GitRefactoringInfo gitInfo, List operations) { var commands = new List(); if (gitInfo?.NewBranchName != null) { var operationsSummary = string.Join(", ", operations); commands.Add("# To commit the refactoring changes:"); commands.Add("git add ."); commands.Add($"git commit -m \"Automated refactoring: {operationsSummary}\""); commands.Add(""); } return commands; } } }