<?php

/**
 * PHP-IR throw statement for minimal PHP Exception support.
 */
final class PhpIrThrow
{
    private int $startLine;
    private int $endLine;
    private array $comments;
    private string $className;
    private ?object $throwableExpr;
    private object $message;
    private object $code;
    private ?object $previous;

    /**
     * Create a throw statement.
     *
     * @param int $startLine Source start line.
     * @param int $endLine Source end line.
     * @param array $comments PHP comments attached to the throw statement.
     * @param string $className PHP exception class name.
     * @param object $message Exception message expression.
     * @param object $code Exception code expression.
     * @param object|null $previous Previous Throwable expression.
     * @param object|null $throwableExpr Existing Throwable expression for `throw $e`.
     */
    public function __construct(int $startLine, int $endLine, array $comments, string $className, object $message, ?object $code = null, ?object $previous = null, ?object $throwableExpr = null)
    {
        $this->startLine = $startLine;
        $this->endLine = $endLine;
        $this->comments = $comments;
        $this->className = $className;
        $this->throwableExpr = $throwableExpr;
        $this->message = $message;
        $this->code = $code ?? new PhpIrIntLiteral($startLine, $endLine, [], 0);
        $this->previous = $previous;
    }

    /**
     * Convert to a plain array for debugging/export.
     */
    public function toArray(): array
    {
        return [
            'kind' => 'Throw',
            'startLine' => $this->startLine,
            'endLine' => $this->endLine,
            'comments' => array_map(static fn (PhpIrComment $comment): array => $comment->toArray(), $this->comments),
            'className' => $this->className,
            'throwableExpr' => $this->throwableExpr !== null && method_exists($this->throwableExpr, 'toArray') ? $this->throwableExpr->toArray() : null,
            'message' => method_exists($this->message, 'toArray') ? $this->message->toArray() : ['kind' => get_debug_type($this->message)],
            'code' => method_exists($this->code, 'toArray') ? $this->code->toArray() : ['kind' => get_debug_type($this->code)],
            'previous' => $this->previous !== null && method_exists($this->previous, 'toArray') ? $this->previous->toArray() : null,
        ];
    }
}
