// ABOUTME: Deployment strategy framework for EdgeConnect apply command
// ABOUTME: Defines interfaces and types for different deployment strategies (recreate, blue-green, rolling)
package v1

import (
	"context"
	"fmt"
	"time"

	"edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/internal/config"
)

// DeploymentStrategy represents the type of deployment strategy
type DeploymentStrategy string

const (
	// StrategyRecreate deletes all instances, updates app, then creates new instances
	StrategyRecreate DeploymentStrategy = "recreate"

	// StrategyBlueGreen creates new instances alongside old ones, then switches traffic (future)
	StrategyBlueGreen DeploymentStrategy = "blue-green"

	// StrategyRolling updates instances one by one with health checks (future)
	StrategyRolling DeploymentStrategy = "rolling"
)

// DeploymentStrategyExecutor defines the interface that all deployment strategies must implement
type DeploymentStrategyExecutor interface {
	// Execute runs the deployment strategy
	Execute(ctx context.Context, plan *DeploymentPlan, config *config.EdgeConnectConfig, manifestContent string) (*ExecutionResult, error)

	// Validate checks if the strategy can be used for this deployment
	Validate(plan *DeploymentPlan) error

	// EstimateDuration provides time estimate for this strategy
	EstimateDuration(plan *DeploymentPlan) time.Duration

	// GetName returns the strategy name
	GetName() DeploymentStrategy
}

// StrategyConfig holds configuration for deployment strategies
type StrategyConfig struct {
	// MaxRetries is the number of times to retry failed operations
	MaxRetries int

	// HealthCheckTimeout is the maximum time to wait for health checks
	HealthCheckTimeout time.Duration

	// ParallelOperations enables parallel execution of operations
	ParallelOperations bool

	// RetryDelay is the delay between retry attempts
	RetryDelay time.Duration
}

// DefaultStrategyConfig returns sensible defaults for strategy configuration
func DefaultStrategyConfig() StrategyConfig {
	return StrategyConfig{
		MaxRetries:         5,                // Retry 5 times
		HealthCheckTimeout: 5 * time.Minute,  // Max 5 mins health check
		ParallelOperations: true,             // Parallel execution
		RetryDelay:         10 * time.Second, // 10s between retries
	}
}

// StrategyFactory creates deployment strategy executors
type StrategyFactory struct {
	config StrategyConfig
	client EdgeConnectClientInterface
	logger Logger
}

// NewStrategyFactory creates a new strategy factory
func NewStrategyFactory(client EdgeConnectClientInterface, config StrategyConfig, logger Logger) *StrategyFactory {
	return &StrategyFactory{
		config: config,
		client: client,
		logger: logger,
	}
}

// CreateStrategy creates the appropriate strategy executor based on the deployment strategy
func (f *StrategyFactory) CreateStrategy(strategy DeploymentStrategy) (DeploymentStrategyExecutor, error) {
	switch strategy {
	case StrategyRecreate:
		return NewRecreateStrategy(f.client, f.config, f.logger), nil
	case StrategyBlueGreen:
		// TODO: Implement blue-green strategy
		return nil, fmt.Errorf("blue-green strategy not yet implemented")
	case StrategyRolling:
		// TODO: Implement rolling strategy
		return nil, fmt.Errorf("rolling strategy not yet implemented")
	default:
		return nil, fmt.Errorf("unknown deployment strategy: %s", strategy)
	}
}

// GetAvailableStrategies returns a list of all available strategies
func (f *StrategyFactory) GetAvailableStrategies() []DeploymentStrategy {
	return []DeploymentStrategy{
		StrategyRecreate,
		// StrategyBlueGreen, // TODO: Enable when implemented
		// StrategyRolling,   // TODO: Enable when implemented
	}
}
