<?php
/**
 * ptyAIConfig
 *
 * AI 공통 설정 로더
 * 설정 파일: ~/.ptyAIConfig.ini
 *
 * 지원 provider:
 * - anthropic: Claude API
 * - openai: ChatGPT API
 * - google: Gemini API
 */

namespace platyFramework;

require_once __DIR__ . "/claude.api.common.model.php";
require_once __DIR__ . "/chatgpt.api.common.model.php";
require_once __DIR__ . "/gemini.api.common.model.php";
require_once __DIR__ . "/ollama.api.common.model.php";

/**
 * AI 설정 로더 클래스
 */
class ptyAIConfig
{
    private static $configPath = null;

    /**
     * 설정 파일 경로 반환
     */
    public static function getConfigPath()
    {
        if (self::$configPath === null) {
            self::$configPath = getenv('HOME') . '/.ptyAIConfig.ini';
        }
        return self::$configPath;
    }

    /**
     * 설정 파일에서 섹션 목록 조회
     */
    public static function getSections()
    {
        $configPath = self::getConfigPath();

        if (!file_exists($configPath)) {
            return [];
        }

        $config = parse_ini_file($configPath, true);
        return $config ? array_keys($config) : [];
    }

    /**
     * AI 설정 로드
     *
     * @param string $section INI 파일 섹션명 (기본값: default)
     * @return array 설정 배열 [provider, model, apiKey]
     * @throws \Exception 설정 파일이나 섹션이 없을 경우
     */
    public static function load($section = 'default')
    {
        $configPath = self::getConfigPath();

        if (!file_exists($configPath)) {
            throw new \Exception("AI 설정 파일을 찾을 수 없습니다: {$configPath}\n\n" . self::getConfigExample());
        }

        $config = parse_ini_file($configPath, true);

        if ($config === false) {
            throw new \Exception("AI 설정 파일을 파싱할 수 없습니다: {$configPath}");
        }

        if (!isset($config[$section])) {
            $availableSections = implode(', ', array_keys($config));
            throw new \Exception("AI 설정에서 [{$section}] 섹션을 찾을 수 없습니다.\n사용 가능한 섹션: {$availableSections}");
        }

        $sectionConfig = $config[$section];

        // provider 먼저 확인
        if (!isset($sectionConfig['provider']) || empty($sectionConfig['provider'])) {
            throw new \Exception("AI 설정 [{$section}] 섹션에 필수 필드 'provider'가 없습니다.");
        }

        $provider = strtolower($sectionConfig['provider']);

        // apiKey 필수 검증 (ollama 제외)
        if ($provider !== 'ollama') {
            if (!isset($sectionConfig['apiKey']) || empty($sectionConfig['apiKey'])) {
                throw new \Exception("AI 설정 [{$section}] 섹션에 필수 필드 'apiKey'가 없습니다.");
            }
        }
        $validProviders = ['anthropic', 'openai', 'google', 'ollama'];
        if (!in_array($provider, $validProviders)) {
            throw new \Exception("AI 설정 [{$section}] 섹션의 provider '{$provider}'는 지원되지 않습니다.\n지원되는 provider: " . implode(', ', $validProviders));
        }

        // anthropic-beta 값 처리 (베타 기능 이름)
        $anthropicBeta = null;
        if (isset($sectionConfig['anthropic-beta']) && !empty($sectionConfig['anthropic-beta'])) {
            $anthropicBeta = trim($sectionConfig['anthropic-beta'], '"\'');
        }

        return [
            'provider' => $provider,
            'model' => $sectionConfig['model'] ?? self::getDefaultModel($provider),
            'apiKey' => isset($sectionConfig['apiKey']) ? trim($sectionConfig['apiKey'], '"\'') : null,
            'apiUrl' => isset($sectionConfig['apiUrl']) ? trim($sectionConfig['apiUrl'], '"\'') : null,
            'anthropic-beta' => $anthropicBeta,
        ];
    }

    /**
     * provider별 기본 모델 반환
     */
    public static function getDefaultModel($provider)
    {
        $defaults = [
            'anthropic' => 'claude-3-5-sonnet-20241022',
            'openai' => 'gpt-4o',
            'google' => 'gemini-2.0-flash-exp',
            'ollama' => 'llama3',
        ];
        return $defaults[$provider] ?? null;
    }

    /**
     * AI 클라이언트 인스턴스 생성
     *
     * @param string $section INI 파일 섹션명 (기본값: default)
     * @return ClaudeAPIModel|ChatGPTAPIModel|GeminiAPIModel
     * @throws \Exception
     */
    public static function createClient($section = 'default')
    {
        $config = self::load($section);

        switch ($config['provider']) {
            case 'anthropic':
                $client = new ClaudeAPIModel($config['apiKey']);
                $client->setModel($config['model']);
                if (!empty($config['anthropic-beta'])) {
                    $client->setAnthropicBeta($config['anthropic-beta']);
                }
                return $client;

            case 'openai':
                $client = new ChatGPTAPIModel();
                $client->setAPIKey($config['apiKey']);
                $client->setModel($config['model']);
                return $client;

            case 'google':
                $client = new GeminiAPIModel($config['apiKey']);
                $client->setModel($config['model']);
                return $client;

            case 'ollama':
                $client = new OllamaAPIModel();
                $client->setModel($config['model']);
                if (!empty($config['apiUrl'])) {
                    $client->setApiUrl($config['apiUrl']);
                }
                return $client;

            default:
                throw new \Exception("지원되지 않는 provider: {$config['provider']}");
        }
    }

    /**
     * 설정 정보와 함께 AI 클라이언트 반환
     *
     * @param string $section INI 파일 섹션명 (기본값: default)
     * @return array [client => object, config => array]
     */
    public static function connect($section = 'default')
    {
        $config = self::load($section);
        $client = self::createClient($section);

        return [
            'client' => $client,
            'config' => $config,
        ];
    }

    /**
     * 설정 파일 예시 반환
     */
    public static function getConfigExample()
    {
        return <<<EOT
설정 파일 예시 (~/.ptyAIConfig.ini):

[default]
provider=anthropic
model=claude-sonnet-4-5-20250514
apiKey=your_anthropic_api_key

[claude-beta]
provider=anthropic
model=claude-sonnet-4-5-20250514
apiKey=your_anthropic_api_key
anthropic-beta=context-1m-2025-08-07

[openai]
provider=openai
model=gpt-4o
apiKey=your_openai_api_key

[google]
provider=google
model=gemini-2.0-flash-exp
apiKey=your_google_api_key

[ollama]
provider=ollama
model=llama3
apiUrl=http://localhost:11434

# 지원 provider: anthropic, openai, google, ollama
# anthropic-beta: Claude 베타 기능 사용 시 헤더값 (예: context-1m-2025-08-07)
# apiUrl: ollama 서버 URL (기본값: http://localhost:11434)
EOT;
    }
}
