<?php

declare(strict_types=1);

namespace App\Framework\Deployment\Pipeline\ValueObjects;

/**
 * Pipeline Configuration
 *
 * Complete configuration for a deployment pipeline including enabled stages,
 * environment-specific settings, and stage parameters.
 */
final readonly class PipelineConfig
{
    /**
     * @param string $name Pipeline configuration name
     * @param DeploymentEnvironment $environment Target deployment environment
     * @param array<StageConfig> $stages Ordered list of stage configurations
     * @param bool $stopOnFailure Stop pipeline execution if a stage fails
     * @param bool $enableRollback Enable automatic rollback on failure
     * @param array<string, mixed> $globalParameters Global parameters available to all stages
     */
    public function __construct(
        public string $name,
        public DeploymentEnvironment $environment,
        public array $stages,
        public bool $stopOnFailure = true,
        public bool $enableRollback = false,
        public array $globalParameters = []
    ) {}

    /**
     * Get stages in execution order
     *
     * @return array<StageConfig>
     */
    public function getStages(): array
    {
        return $this->stages;
    }

    /**
     * Get enabled stages only
     *
     * @return array<StageConfig>
     */
    public function getEnabledStages(): array
    {
        return array_filter(
            $this->stages,
            fn(StageConfig $config) => $config->enabled
        );
    }

    /**
     * Find stage configuration by stage type
     */
    public function findStage(PipelineStage $stage): ?StageConfig
    {
        foreach ($this->stages as $stageConfig) {
            if ($stageConfig->stage === $stage) {
                return $stageConfig;
            }
        }

        return null;
    }

    /**
     * Check if a specific stage is enabled
     */
    public function isStageEnabled(PipelineStage $stage): bool
    {
        $stageConfig = $this->findStage($stage);

        return $stageConfig !== null && $stageConfig->enabled;
    }

    /**
     * Get global parameter value
     */
    public function getGlobalParameter(string $key, mixed $default = null): mixed
    {
        return $this->globalParameters[$key] ?? $default;
    }

    /**
     * Create a modified copy with different environment
     */
    public function forEnvironment(DeploymentEnvironment $environment): self
    {
        return new self(
            name: $this->name,
            environment: $environment,
            stages: $this->stages,
            stopOnFailure: $this->stopOnFailure,
            enableRollback: $this->enableRollback,
            globalParameters: $this->globalParameters
        );
    }
}
