#!/usr/bin/env php
<?php
/**
 * ptyElasticGetIndexs
 *
 * Elasticsearch 인덱스 목록을 조회하는 도구
 * 설정 파일: ~/.ptyElasticConfig.ini
 *
 * Usage: ./ptyElasticGetIndexs [--elastic=섹션명]
 */

namespace platyFramework;

require_once __DIR__ . '/ptyLibrary_PHP/cli/ptyCliOptionParser.php';
require_once __DIR__ . '/ptyLibrary_PHP/elastic/ptyElasticConfig.php';

// 인자 파싱
$parsed = ptyCliOptionParser::parse($argv);
$options = $parsed['options'];
$elasticSection = $options['elastic'] ?? 'default';
$verbose = isset($options['verbose']);

// 도움말 요청시
if (isset($options['help'])) {
    echo "사용법: {$argv[0]} [옵션]\n";
    echo "\n";
    echo "Elasticsearch 인덱스 목록을 조회합니다.\n";
    echo "\n";
    echo "옵션:\n";
    echo "  --elastic=섹션명    INI 파일 섹션 (기본값: default)\n";
    echo "  --verbose           상세 로그 출력\n";
    echo "  --help              도움말 출력\n";
    echo "\n";
    echo "예시:\n";
    echo "  {$argv[0]}\n";
    echo "  {$argv[0]} --elastic=production\n";
    echo "  {$argv[0]} --verbose\n";
    echo "\n";
    echo "설정 파일: ~/.ptyElasticConfig.ini\n";
    echo ptyElasticConfig::getConfigExample() . "\n";
    exit(0);
}

// 타임스탬프 형식 변환
function formatTimestamp($timestamp) {
    if (is_numeric($timestamp) && strlen($timestamp) >= 13) {
        $seconds = intval($timestamp / 1000);
        return date('Y-m-d H:i:s', $seconds);
    }
    if (is_numeric($timestamp) && strlen($timestamp) == 10) {
        return date('Y-m-d H:i:s', intval($timestamp));
    }
    if (is_string($timestamp)) {
        return substr($timestamp, 0, 19);
    }
    return $timestamp;
}

// 인덱스의 마지막 문서 시간 조회
function getLastDocumentTime($elastic, $indexName) {
    try {
        $response = $elastic->search($indexName . '/_search', [
            'size' => 1,
            'sort' => [['_index' => ['order' => 'desc']]],
            'query' => ['match_all' => (object)[]]
        ]);

        if (isset($response['hits']['hits'][0]['_source'])) {
            $source = $response['hits']['hits'][0]['_source'];
            foreach (['@timestamp', 'timestamp', 'created_at', 'updated_at', 'date', 'createdAt', 'updatedAt'] as $field) {
                if (isset($source[$field])) {
                    return formatTimestamp($source[$field]);
                }
            }
        }
        return 'N/A';
    } catch (\Exception $e) {
        return 'N/A';
    }
}

try {
    // Elasticsearch 연결
    $connection = ptyElasticConfig::connect($elasticSection);
    $elastic = $connection['client'];
    $elastic->setDebug($verbose);
    $config = $connection['config'];
    $authMethod = $connection['authMethod'];

    echo "Elasticsearch 인덱스 정보 조회 중...\n";
    echo "Host: {$config['host']} ({$authMethod})\n";
    echo "섹션: {$elasticSection}\n";
    echo str_repeat("=", 80) . "\n\n";

    // 인덱스 정보 조회
    $response = $elastic->get('_cat/indices?v&format=json&bytes=mb&h=index,status,docs.count,store.size,health,pri,rep,creation.date.string');

    if (empty($response)) {
        echo "인덱스가 없습니다.\n";
        exit(0);
    }

    // 결과 정렬 (인덱스 이름순)
    usort($response, function($a, $b) {
        return strcmp($a['index'], $b['index']);
    });

    // 헤더 출력
    printf("%-40s %-10s %-12s %-12s %-10s %-10s %-20s %-20s\n",
        "INDEX", "STATUS", "DOCS.COUNT", "STORE.SIZE", "HEALTH", "PRI/REP", "CREATED", "LAST INDEXED");
    echo str_repeat("-", 165) . "\n";

    // 각 인덱스 정보 출력
    $totalDocs = 0;
    $totalSize = 0;

    foreach ($response as $index) {
        $indexName = $index['index'] ?? 'N/A';
        $status = $index['status'] ?? 'N/A';
        $docsCount = $index['docs.count'] ?? '0';
        $storeSize = $index['store.size'] ?? '0';
        $health = $index['health'] ?? 'N/A';
        $pri = $index['pri'] ?? '0';
        $rep = $index['rep'] ?? '0';
        $creationDate = $index['creation.date.string'] ?? 'N/A';

        // 마지막 색인 시간 조회
        $lastIndexed = 'N/A';
        if ($docsCount !== '0' && is_numeric($docsCount)) {
            $lastIndexed = getLastDocumentTime($elastic, $indexName);
        }

        // 숫자 형식 정리
        $docsCountFormatted = is_numeric($docsCount) ? number_format($docsCount) : $docsCount;

        // 용량 형식 정리
        $storeSizeFormatted = is_numeric($storeSize) ? number_format($storeSize, 2) . ' MB' : $storeSize;

        printf("%-40s %-10s %-12s %-12s %-10s %-10s %-20s %-20s\n",
            substr($indexName, 0, 40),
            $status,
            $docsCountFormatted,
            $storeSizeFormatted,
            $health,
            $pri . '/' . $rep,
            substr($creationDate, 0, 20),
            substr($lastIndexed, 0, 20)
        );

        // 총합 계산
        if (is_numeric($docsCount)) {
            $totalDocs += intval($docsCount);
        }
        if (is_numeric($storeSize)) {
            $totalSize += floatval($storeSize);
        }
    }

    // 요약 정보 출력
    echo str_repeat("=", 165) . "\n";
    printf("총 인덱스 수: %d\n", count($response));
    printf("총 문서 수: %s\n", number_format($totalDocs));
    printf("총 용량: %.2f MB (%.2f GB)\n", $totalSize, $totalSize / 1024);

} catch (\Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
    exit(1);
}
