<?php
/**
 * ptyElasticConfig
 *
 * Elasticsearch 공통 설정 로더
 * 설정 파일: ~/.ptyElasticConfig.ini
 *
 * 지원 인증 방식:
 * - apiKey: API Key 인증
 * - user/password: Basic 인증
 */

namespace platyFramework;

require_once __DIR__ . "/../cli/ptyCliLog.php";
require_once __DIR__ . "/Elastic.php";

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

    /**
     * 설정 파일 경로 반환
     */
    public static function getConfigPath()
    {
        if (self::$configPath === null) {
            self::$configPath = getenv('HOME') . '/.ptyElasticConfig.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) : [];
    }

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

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

        $config = parse_ini_file($configPath, true);

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

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

        $sectionConfig = $config[$section];

        // 필수 필드 검증
        if (!isset($sectionConfig['host']) || empty($sectionConfig['host'])) {
            throw new \Exception("Elasticsearch 설정 [{$section}] 섹션에 필수 필드 'host'가 없습니다.");
        }

        return [
            'host' => $sectionConfig['host'],
            'apiKey' => isset($sectionConfig['apiKey']) ? trim($sectionConfig['apiKey'], '"\'') : null,
            'user' => $sectionConfig['user'] ?? null,
            'password' => isset($sectionConfig['password']) ? trim($sectionConfig['password'], '"\'') : null,
        ];
    }

    /**
     * Elastic 클래스 인스턴스 생성
     *
     * @param string $section INI 파일 섹션명 (기본값: default)
     * @return Elastic
     */
    public static function createClient($section = 'default')
    {
        $config = self::load($section);

        return new Elastic(
            $config['apiKey'],
            $config['host'],
            null,
            $config['user'],
            $config['password']
        );
    }

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

        $client = new Elastic(
            $config['apiKey'],
            $config['host'],
            null,
            $config['user'],
            $config['password']
        );

        $authMethod = !empty($config['apiKey']) ? 'apiKey' : 'user/password';

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

    /**
     * 인증 헤더 생성 (curl용)
     *
     * @param array $config 설정 배열
     * @return array HTTP 헤더 배열
     */
    public static function getAuthHeaders($config)
    {
        $headers = ['Content-Type: application/json'];

        if (!empty($config['apiKey'])) {
            $headers[] = 'Authorization: ApiKey ' . $config['apiKey'];
        } elseif (!empty($config['user']) && !empty($config['password'])) {
            $headers[] = 'Authorization: Basic ' . base64_encode($config['user'] . ':' . $config['password']);
        }

        return $headers;
    }

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

[default]
host=https://localhost:9200
apiKey=your_api_key

# 또는 user/password 방식
# [default]
# host=https://localhost:9200
# user=elastic
# password="your_password"
EOT;
    }

    /**
     * 사용법 출력
     */
    public static function printUsage($scriptName, $extraArgs = '', $extraOptions = '')
    {
        $sections = self::getSections();
        $sectionsStr = empty($sections) ? '(설정 파일 없음)' : implode(', ', $sections);

        echo "\n";
        echo "사용법: {$scriptName} {$extraArgs}[--elastic=섹션명]\n";
        echo "\n";
        echo "설정 파일: ~/.ptyElasticConfig.ini\n";
        echo "사용 가능한 섹션: {$sectionsStr}\n";
        echo "\n";
        if ($extraOptions) {
            echo "옵션:\n";
            echo $extraOptions;
            echo "\n";
        }
        echo "  --elastic=섹션명    INI 파일 섹션 (기본값: default)\n";
        echo "\n";
        echo self::getConfigExample();
        echo "\n";
    }
}
