<?php
namespace boru\ai\Runtime;

class ToolDefinition
{
    /** @var string */
    protected $name;

    /** @var string */
    protected $description = '';

    /** @var array */
    protected $schema = array(
        'type' => 'object',
        'properties' => array(),
    );

    /** @var callable|null */
    protected $callback;

    /** @var array */
    protected $metadata = array();

    public function name($value = null)
    {
        if ($value !== null) {
            $this->name = (string)$value;
            return $this;
        }
        return $this->name;
    }

    public function description($value = null)
    {
        if ($value !== null) {
            $this->description = (string)$value;
            return $this;
        }
        return $this->description;
    }

    public function schema($value = null)
    {
        if ($value !== null) {
            $this->schema = is_array($value) ? $value : array();
            return $this;
        }
        return $this->schema;
    }

    public function callback($value = null)
    {
        if ($value !== null) {
            if (!is_callable($value)) {
                throw new \InvalidArgumentException('Tool callback must be callable');
            }
            $this->callback = $value;
            return $this;
        }
        return $this->callback;
    }

    public function metadata($key = null, $value = null)
    {
        if ($key === null) {
            return $this->metadata;
        }
        if (is_array($key)) {
            $this->metadata = $key;
            return $this;
        }
        if (func_num_args() > 1) {
            $this->metadata[$key] = $value;
            return $this;
        }
        return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
    }

    public function invoke(array $arguments, ToolExecutionContext $context = null)
    {
        if (!$this->callback) {
            throw new \RuntimeException('Tool has no callback: ' . $this->name());
        }
        return call_user_func($this->callback, $arguments, $context, $this);
    }

    public function toArray()
    {
        return array(
            'name' => $this->name(),
            'description' => $this->description(),
            'schema' => $this->schema(),
            'metadata' => $this->metadata(),
        );
    }
}
