package git

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"sync"
)

// CloneManager manages separate Git repository clones for each agent
// This eliminates Git concurrency issues by giving each agent its own working directory
type CloneManager struct {
	baseRepoURL   string
	workspacePath string
	agentClones   map[string]string // agent name -> clone path
	mu            sync.RWMutex
}

// NewCloneManager creates a new CloneManager
func NewCloneManager(baseRepoURL, workspacePath string) *CloneManager {
	return &CloneManager{
		baseRepoURL:   baseRepoURL,
		workspacePath: workspacePath,
		agentClones:   make(map[string]string),
	}
}

// GetAgentClonePath returns the Git clone path for a specific agent
// Creates the clone if it doesn't exist
func (cm *CloneManager) GetAgentClonePath(agentName string) (string, error) {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	// Check if clone already exists
	if clonePath, exists := cm.agentClones[agentName]; exists {
		// Verify the clone still exists on disk
		if _, err := os.Stat(clonePath); err == nil {
			return clonePath, nil
		}
		// Remove stale entry if directory doesn't exist
		delete(cm.agentClones, agentName)
	}

	// Create new clone for the agent
	clonePath := filepath.Join(cm.workspacePath, fmt.Sprintf("agent-%s", agentName))

	// Ensure workspace directory exists
	if err := os.MkdirAll(cm.workspacePath, 0755); err != nil {
		return "", fmt.Errorf("failed to create workspace directory: %w", err)
	}

	// Remove existing clone directory if it exists
	if err := os.RemoveAll(clonePath); err != nil {
		return "", fmt.Errorf("failed to remove existing clone: %w", err)
	}

	// Clone the repository
	if err := cm.cloneRepository(clonePath); err != nil {
		return "", fmt.Errorf("failed to clone repository for agent %s: %w", agentName, err)
	}

	// Store the clone path
	cm.agentClones[agentName] = clonePath

	return clonePath, nil
}

// cloneRepository performs the actual Git clone operation
func (cm *CloneManager) cloneRepository(clonePath string) error {
	ctx := context.Background()

	// Clone the repository
	cmd := exec.CommandContext(ctx, "git", "clone", cm.baseRepoURL, clonePath)
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("git clone failed: %w", err)
	}

	return nil
}

// RefreshAgentClone pulls the latest changes for an agent's clone
func (cm *CloneManager) RefreshAgentClone(agentName string) error {
	cm.mu.RLock()
	clonePath, exists := cm.agentClones[agentName]
	cm.mu.RUnlock()

	if !exists {
		return fmt.Errorf("no clone exists for agent %s", agentName)
	}

	ctx := context.Background()

	// Change to clone directory and pull latest changes
	cmd := exec.CommandContext(ctx, "git", "-C", clonePath, "pull", "origin")
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to pull latest changes for agent %s: %w", agentName, err)
	}

	return nil
}

// CleanupAgentClone removes the clone directory for an agent
func (cm *CloneManager) CleanupAgentClone(agentName string) error {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	clonePath, exists := cm.agentClones[agentName]
	if !exists {
		return nil // Already cleaned up
	}

	// Remove the clone directory
	if err := os.RemoveAll(clonePath); err != nil {
		return fmt.Errorf("failed to remove clone for agent %s: %w", agentName, err)
	}

	// Remove from tracking
	delete(cm.agentClones, agentName)

	return nil
}

// CleanupAllClones removes all agent clone directories
func (cm *CloneManager) CleanupAllClones() error {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	var errors []error

	for agentName, clonePath := range cm.agentClones {
		if err := os.RemoveAll(clonePath); err != nil {
			errors = append(errors, fmt.Errorf("failed to remove clone for agent %s: %w", agentName, err))
		}
	}

	// Clear all tracked clones
	cm.agentClones = make(map[string]string)

	if len(errors) > 0 {
		return fmt.Errorf("cleanup errors: %v", errors)
	}

	return nil
}
