#!/usr/bin/env php
<?php
/**
 * ptyElasticTruncateIndex
 *
 * Elasticsearch 인덱스의 모든 문서를 삭제하는 도구
 * 설정 파일: ~/.ptyElasticConfig.ini
 *
 * Usage: ./ptyElasticTruncateIndex <index_name> [--elastic=섹션명]
 */

namespace platyFramework;

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

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

// 도움말 또는 인덱스명 확인
if (empty($positionalArgs) || isset($options['help'])) {
    echo "사용법: {$argv[0]} <index_name> [--elastic=섹션명]\n";
    echo "\n";
    echo "옵션:\n";
    echo "  --elastic=섹션명    INI 파일 섹션 (기본값: default)\n";
    echo "  --verbose           상세 로그 출력\n";
    echo "  --help              도움말 출력\n";
    echo "\n";
    echo "예시:\n";
    echo "  {$argv[0]} my_index\n";
    echo "  {$argv[0]} my_index --elastic=production\n";
    echo "\n";
    echo "Warning: This will DELETE ALL DOCUMENTS in the index!\n";
    echo "\n";
    echo "설정 파일: ~/.ptyElasticConfig.ini\n";
    echo ptyElasticConfig::getConfigExample() . "\n";
    exit(isset($options['help']) ? 0 : 1);
}

$indexName = $positionalArgs[0];

// 바이트를 읽기 쉬운 형식으로 변환
function formatBytes($bytes) {
    if ($bytes >= 1073741824) {
        return number_format($bytes / 1073741824, 2) . ' GB';
    } elseif ($bytes >= 1048576) {
        return number_format($bytes / 1048576, 2) . ' MB';
    } elseif ($bytes >= 1024) {
        return number_format($bytes / 1024, 2) . ' KB';
    } else {
        return $bytes . ' bytes';
    }
}

try {
    // 색상 코드 정의
    $redColor = "\033[1;31m";
    $yellowColor = "\033[1;33m";
    $greenColor = "\033[1;32m";
    $cyanColor = "\033[1;36m";
    $resetColor = "\033[0m";

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

    echo "{$redColor}WARNING: Elasticsearch 인덱스 전체 삭제{$resetColor}\n";
    echo "Host: {$config['host']} ({$authMethod})\n";
    echo "Index: {$yellowColor}$indexName{$resetColor}\n";
    echo str_repeat("=", 100) . "\n\n";

    // 1. 인덱스 정보 조회
    echo "{$cyanColor}[ 인덱스 정보 ]{$resetColor}\n";
    echo str_repeat("-", 100) . "\n";

    $catData = $elastic->get('_cat/indices/' . urlencode($indexName) . '?v&format=json&bytes=b');

    if (empty($catData)) {
        throw new \Exception("인덱스를 찾을 수 없습니다: $indexName");
    }

    $indexInfo = $catData[0];
    printf("상태(Health): %s\n", $indexInfo['health'] ?? 'N/A');
    printf("상태(Status): %s\n", $indexInfo['status'] ?? 'N/A');
    printf("문서 수: {$yellowColor}%s{$resetColor}\n", number_format($indexInfo['docs.count'] ?? 0));
    printf("저장 용량: {$yellowColor}%s{$resetColor}\n", formatBytes($indexInfo['store.size'] ?? 0));
    echo "\n";

    // 2. 샘플 문서 10개 표시
    echo "{$cyanColor}[ 샘플 문서 10개 ]{$resetColor}\n";
    echo str_repeat("-", 100) . "\n";

    $searchData = $elastic->search(urlencode($indexName) . '/_search', [
        'size' => 10,
        'query' => ['match_all' => (object)[]]
    ]);

    if (isset($searchData['hits']['hits']) && count($searchData['hits']['hits']) > 0) {
        $hits = $searchData['hits']['hits'];

        foreach ($hits as $idx => $hit) {
            $docId = $hit['_id'];
            echo "\n문서 #" . ($idx + 1) . " (ID: {$greenColor}{$docId}{$resetColor})\n";

            $source = $hit['_source'];
            $displayCount = 0;

            foreach ($source as $key => $value) {
                if ($displayCount >= 3) {
                    $remainingFields = count($source) - $displayCount;
                    if ($remainingFields > 0) {
                        echo "  ... 외 $remainingFields 개 필드 더 있음\n";
                    }
                    break;
                }

                if (is_array($value) || is_object($value)) {
                    $valueStr = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                    if (strlen($valueStr) > 80) {
                        $valueStr = substr($valueStr, 0, 80) . "...";
                    }
                    echo "  $key: $valueStr\n";
                } else {
                    $valueStr = is_string($value) ? $value : json_encode($value);
                    if (strlen($valueStr) > 80) {
                        $valueStr = substr($valueStr, 0, 80) . "...";
                    }
                    echo "  $key: $valueStr\n";
                }
                $displayCount++;
            }
        }

        echo "\n총 샘플 문서 수: " . count($hits) . "\n";
        echo "전체 문서 수: {$yellowColor}" . number_format($searchData['hits']['total']['value'] ?? 0) . "{$resetColor}\n";
    } else {
        echo "문서가 없습니다.\n";
    }

    echo "\n" . str_repeat("=", 100) . "\n";

    // 3. 삭제 확인
    echo "\n{$redColor}경고: 이 작업은 인덱스 '$indexName'의 모든 문서를 삭제합니다!{$resetColor}\n";
    echo "{$redColor}인덱스 자체는 삭제되지 않지만, 모든 데이터가 사라집니다.{$resetColor}\n";
    echo "\n계속하시겠습니까? 삭제하려면 '{$greenColor}yes{$resetColor}'를 입력하세요: ";

    $handle = fopen("php://stdin", "r");
    $line = trim(fgets($handle));
    fclose($handle);

    if ($line !== 'yes') {
        echo "\n취소되었습니다. 아무 변경도 일어나지 않았습니다.\n";
        exit(0);
    }

    // 4. 모든 문서 삭제
    echo "\n{$yellowColor}삭제 중...{$resetColor}\n";

    $deleteData = $elastic->post(urlencode($indexName) . '/_delete_by_query?conflicts=proceed', [
        'query' => ['match_all' => (object)[]]
    ]);

    // 5. 결과 표시
    echo "\n" . str_repeat("=", 100) . "\n";
    echo "{$greenColor}삭제 완료!{$resetColor}\n";
    echo str_repeat("=", 100) . "\n";

    printf("삭제된 문서 수: {$greenColor}%s{$resetColor}\n", number_format($deleteData['deleted'] ?? 0));
    printf("실패한 문서 수: %s\n", number_format(count($deleteData['failures'] ?? [])));
    printf("소요 시간: %s ms\n", number_format($deleteData['took'] ?? 0));

    if (!empty($deleteData['failures'])) {
        echo "\n{$redColor}일부 문서 삭제에 실패했습니다. 로그를 확인하세요.{$resetColor}\n";
    }

    echo "\n";

} catch (\Exception $e) {
    $redColor = "\033[1;31m";
    $resetColor = "\033[0m";
    echo "{$redColor}Error: " . $e->getMessage() . "{$resetColor}\n";
    exit(1);
}
