<?php

declare(strict_types=1);

namespace App\Framework\Process;

use App\Framework\Console\ExitCode;
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Process\ValueObjects\Command;

/**
 * Repräsentiert das Ergebnis einer Prozess-Ausführung.
 */
final readonly class ProcessResult
{
    public function __construct(
        public Command $command,
        public string $stdout,
        public string $stderr,
        public ExitCode $exitCode,
        public Duration $runtime
    ) {
    }

    /**
     * Prüft, ob der Prozess erfolgreich war (Exit Code 0).
     */
    public function isSuccess(): bool
    {
        return $this->exitCode->isSuccess();
    }

    /**
     * Prüft, ob der Prozess fehlgeschlagen ist.
     */
    public function isFailed(): bool
    {
        return $this->exitCode->isError();
    }

    /**
     * Gibt die Standard-Ausgabe zurück.
     */
    public function getOutput(): string
    {
        return $this->stdout;
    }

    /**
     * Gibt die Fehler-Ausgabe zurück.
     */
    public function getErrorOutput(): string
    {
        return $this->stderr;
    }

    /**
     * Prüft, ob Standard-Ausgabe vorhanden ist.
     */
    public function hasOutput(): bool
    {
        return ! empty($this->stdout);
    }

    /**
     * Prüft, ob Fehler-Ausgabe vorhanden ist.
     */
    public function hasErrors(): bool
    {
        return ! empty($this->stderr);
    }

    /**
     * Gibt die kombinierte Ausgabe (stdout + stderr) zurück.
     */
    public function getCombinedOutput(): string
    {
        return trim($this->stdout . "\n" . $this->stderr);
    }

    /**
     * Gibt das Ergebnis als Array zurück.
     *
     * @return array{
     *     command: string,
     *     stdout: string,
     *     stderr: string,
     *     exit_code: int,
     *     exit_description: string,
     *     runtime_ms: float,
     *     success: bool
     * }
     */
    public function toArray(): array
    {
        return [
            'command' => $this->command->toString(),
            'stdout' => $this->stdout,
            'stderr' => $this->stderr,
            'exit_code' => $this->exitCode->value,
            'exit_description' => $this->exitCode->getDescription(),
            'runtime_ms' => $this->runtime->toMilliseconds(),
            'success' => $this->isSuccess(),
        ];
    }
}
