// Package backends provides modular screen capture implementations.
//
// Supports various capture sources:
// - Window capture (Win32, X11)
// - Wayland desktop capture
// - VNC client capture
// - SPICE capture for VMs
// - Monitor/screen region capture
// - File-based capture (for testing)
package backends

import (
	"fmt"
	"strings"

	"git.cloonar.com/openclawd/iso-bot/pkg/engine/capture"
)

// BackendType identifies a capture backend implementation.
type BackendType string

const (
	BackendWindowWin32 BackendType = "window_win32"
	BackendWindowX11   BackendType = "window_x11"
	BackendWayland     BackendType = "wayland"
	BackendVNC         BackendType = "vnc"
	BackendSpice       BackendType = "spice"
	BackendMonitor     BackendType = "monitor"
	BackendFile        BackendType = "file"
)

// BackendInfo describes a capture backend.
type BackendInfo struct {
	Type        BackendType
	Name        string
	Description string
	Available   bool // true if backend can be used on this platform
}

// Registry manages available capture backends.
type Registry struct {
	backends map[BackendType]func(map[string]interface{}) (capture.Source, error)
}

// NewRegistry creates a new backend registry.
func NewRegistry() *Registry {
	return &Registry{
		backends: make(map[BackendType]func(map[string]interface{}) (capture.Source, error)),
	}
}

// Register registers a backend constructor.
func (r *Registry) Register(backendType BackendType, constructor func(map[string]interface{}) (capture.Source, error)) {
	r.backends[backendType] = constructor
}

// Create creates a capture source of the specified type with the given config.
func (r *Registry) Create(backendType BackendType, config map[string]interface{}) (capture.Source, error) {
	constructor, exists := r.backends[backendType]
	if !exists {
		return nil, fmt.Errorf("backend %q not registered", backendType)
	}
	return constructor(config)
}

// ListAvailable returns information about available backends.
func (r *Registry) ListAvailable() []BackendInfo {
	var infos []BackendInfo

	for backendType := range r.backends {
		info := BackendInfo{
			Type:      backendType,
			Available: true,
		}

		switch backendType {
		case BackendWindowWin32:
			info.Name = "Windows Window Capture"
			info.Description = "Capture specific window using BitBlt/DXGI APIs"
		case BackendWindowX11:
			info.Name = "X11 Window Capture"
			info.Description = "Capture specific window using XGetImage"
		case BackendWayland:
			info.Name = "Wayland Screen Capture"
			info.Description = "Screen capture via PipeWire/xdg-desktop-portal"
		case BackendVNC:
			info.Name = "VNC Client Capture"
			info.Description = "Capture frames from VNC server"
		case BackendSpice:
			info.Name = "SPICE VM Capture"
			info.Description = "Capture from QEMU/KVM SPICE display"
		case BackendMonitor:
			info.Name = "Monitor Capture"
			info.Description = "Full screen or monitor region capture"
		case BackendFile:
			info.Name = "File Input"
			info.Description = "Read from image files or video streams"
		}

		infos = append(infos, info)
	}

	return infos
}

// ParseBackendType parses a backend type string.
func ParseBackendType(s string) (BackendType, error) {
	switch strings.ToLower(s) {
	case "window_win32":
		return BackendWindowWin32, nil
	case "window_x11":
		return BackendWindowX11, nil
	case "wayland":
		return BackendWayland, nil
	case "vnc":
		return BackendVNC, nil
	case "spice":
		return BackendSpice, nil
	case "monitor":
		return BackendMonitor, nil
	case "file":
		return BackendFile, nil
	default:
		return "", fmt.Errorf("unknown backend type: %q", s)
	}
}

// GetDefault returns the default backend registry with all available backends registered.
func GetDefault() *Registry {
	reg := NewRegistry()

	// Always register these core backends that work on all platforms
	reg.Register(BackendFile, NewFileSource)
	
	// Platform-specific backends are registered via init() functions
	// with appropriate build tags to avoid compilation errors
	
	return reg
}

// init function registers platform-specific backends.
// Each platform will have its own init function with build tags.
func init() {
	defaultRegistry := GetDefault()
	
	// Register monitor backend (should work on most platforms)
	if MonitorSourceAvailable() {
		defaultRegistry.Register(BackendMonitor, NewMonitorSource)
	}
	
	// Other backends registered via platform-specific init() functions
}