<?php
namespace boru\ai\Tests\Provider;

use boru\ai\Config\Config;
use boru\ai\Provider\Gemini\GeminiClient;
use boru\ai\Provider\OpenAI\OpenAIClient;
use PHPUnit\Framework\TestCase;

class ClientConfigResolutionTest extends TestCase
{
    protected function tearDown(): void
    {
        putenv('AI_TIMEOUT');
        putenv('AI_RAW_HTTP_DEBUG');
        putenv('AI_STREAM_READ_SIZE');
        putenv('GEMINI_TIMEOUT');
        putenv('GEMINI_RAW_HTTP_DEBUG');
        putenv('GEMINI_STREAM_READ_SIZE');
        putenv('OPENAI_TIMEOUT');
        putenv('OPENAI_RAW_HTTP_DEBUG');
        putenv('OPENAI_STREAM_READ_SIZE');
    }

    public function testGeminiClientResolvesKnobsWithExpectedPrecedence()
    {
        $config = new Config();
        $config->runtime(array(
            'timeout' => 30,
            'raw_http_debug' => false,
            'stream_read_size' => 512,
        ));
        $config->provider('gemini', array(
            'timeout' => 45,
            'raw_http_debug' => true,
            'stream_read_size' => 256,
        ));

        putenv('AI_TIMEOUT=90');
        putenv('AI_RAW_HTTP_DEBUG=0');
        putenv('AI_STREAM_READ_SIZE=128');
        putenv('GEMINI_TIMEOUT=120');
        putenv('GEMINI_RAW_HTTP_DEBUG=1');
        putenv('GEMINI_STREAM_READ_SIZE=64');

        $client = new GeminiClient('test-key', $config->provider('gemini'));

        $this->assertSame(120, $this->getProperty($client, 'timeout'));
        $this->assertTrue($this->getProperty($client, 'rawHttpDebug'));
        $this->assertSame(64, $this->getProperty($client, 'streamReadSize'));
    }

    public function testOpenAIClientResolvesKnobsWithExpectedPrecedence()
    {
        $config = new Config();
        $config->runtime(array(
            'timeout' => 30,
            'raw_http_debug' => false,
            'stream_read_size' => 512,
        ));
        $config->provider('openai', array(
            'timeout' => 45,
            'raw_http_debug' => true,
            'stream_read_size' => 256,
        ));

        putenv('AI_TIMEOUT=90');
        putenv('AI_RAW_HTTP_DEBUG=0');
        putenv('AI_STREAM_READ_SIZE=128');
        putenv('OPENAI_TIMEOUT=75');
        putenv('OPENAI_RAW_HTTP_DEBUG=1');
        putenv('OPENAI_STREAM_READ_SIZE=32');

        $client = new OpenAIClient('test-key', $config->provider('openai'));

        $this->assertSame(75, $this->getProperty($client, 'timeout'));
        $this->assertTrue($this->getProperty($client, 'rawHttpDebug'));
        $this->assertSame(32, $this->getProperty($client, 'streamReadSize'));
    }

    protected function getProperty($object, $property)
    {
        $reflection = new \ReflectionObject($object);
        $prop = $reflection->getProperty($property);
        $prop->setAccessible(true);
        return $prop->getValue($object);
    }
}
