<?php

/**
 * PHP-IR instance method call expression/statement: $receiver->method(...).
 */
final class PhpIrMethodCall
{
    private int $startLine;
    private int $endLine;
    private array $comments;
    private object $receiver;
    private ?string $methodName;
    private ?object $methodNameExpression;
    private array $args;
    private string $currentClassScope;

    /**
     * Create this PHP-IR node.
     */
    public function __construct(int $startLine, int $endLine, array $comments, object $receiver, ?string $methodName, array $args, string $currentClassScope = '', ?object $methodNameExpression = null)
    {
        $this->startLine = $startLine;
        $this->endLine = $endLine;
        $this->comments = $comments;
        $this->receiver = $receiver;
        $this->methodName = $methodName;
        $this->methodNameExpression = $methodNameExpression;
        $this->args = $args;
        $this->currentClassScope = $currentClassScope;
    }

    /**
     * Convert to a plain array for debugging/export.
     */
    public function toArray(): array
    {
        return [
            'kind' => 'MethodCall',
            'startLine' => $this->startLine,
            'endLine' => $this->endLine,
            'comments' => array_map(static fn (PhpIrComment $comment): array => $comment->toArray(), $this->comments),
            'receiver' => method_exists($this->receiver, 'toArray') ? $this->receiver->toArray() : ['kind' => get_debug_type($this->receiver)],
            'methodName' => $this->methodName,
            'methodNameExpression' => $this->methodNameExpression !== null
                ? (method_exists($this->methodNameExpression, 'toArray') ? $this->methodNameExpression->toArray() : ['kind' => get_debug_type($this->methodNameExpression)])
                : null,
            'args' => array_map(
                static fn (object $arg): array => method_exists($arg, 'toArray') ? $arg->toArray() : ['kind' => get_debug_type($arg)],
                $this->args,
            ),
            'currentClassScope' => $this->currentClassScope,
        ];
    }
}
