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

// 커맨드 라인 인자 확인
if ($argc < 2) {
    echo "Usage: $argv[0] <index_name>\n";
    echo "Example: $argv[0] my_index\n";
    echo "\nWarning: This will DELETE ALL DOCUMENTS in the index!\n";
    exit(1);
}

$indexName = $argv[1];

// 설정 파일 경로
$configFile = getenv('HOME') . '/.ptyElasticConfig.ini';

// 설정 파일 확인
if (!file_exists($configFile)) {
    echo "Error: 설정 파일을 찾을 수 없습니다: $configFile\n";
    echo "\n설정 파일 예시:\n";
    echo "[elastic]\n";
    echo "host=https://localhost:9200\n";
    echo "user=elastic\n";
    echo "password=yourpassword\n";
    exit(1);
}

// 설정 파일 읽기
$config = parse_ini_file($configFile, true);

if (!isset($config['elastic'])) {
    echo "Error: 설정 파일에 [elastic] 섹션이 없습니다.\n";
    exit(1);
}

$elasticConfig = $config['elastic'];
$host = $elasticConfig['host'] ?? '';
$user = $elasticConfig['user'] ?? '';
$password = $elasticConfig['password'] ?? '';

if (empty($host)) {
    echo "Error: host 설정이 필요합니다.\n";
    exit(1);
}

// Elasticsearch API 호출
function callElasticAPI($url, $user, $password, $method = 'GET', $body = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);

    if ($body !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    }

    if (!empty($user) && !empty($password)) {
        curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
    }

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if (curl_errno($ch)) {
        $error = curl_error($ch);
        curl_close($ch);
        throw new Exception("cURL Error: $error");
    }

    curl_close($ch);

    if ($httpCode !== 200) {
        throw new Exception("HTTP Error: $httpCode - $response");
    }

    return $response;
}

// 바이트를 읽기 쉬운 형식으로 변환
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";

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

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

    $catUrl = rtrim($host, '/') . '/_cat/indices/' . urlencode($indexName) . '?v&format=json&bytes=b';
    $catResponse = callElasticAPI($catUrl, $user, $password);
    $catData = json_decode($catResponse, true);

    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";

    $searchUrl = rtrim($host, '/') . '/' . urlencode($indexName) . '/_search';
    $searchBody = json_encode([
        'size' => 10,
        'query' => ['match_all' => (object)[]]
    ]);

    $searchResponse = callElasticAPI($searchUrl, $user, $password, 'POST', $searchBody);
    $searchData = json_decode($searchResponse, true);

    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";

    $deleteUrl = rtrim($host, '/') . '/' . urlencode($indexName) . '/_delete_by_query?conflicts=proceed';
    $deleteBody = json_encode([
        'query' => ['match_all' => (object)[]]
    ]);

    $deleteResponse = callElasticAPI($deleteUrl, $user, $password, 'POST', $deleteBody);
    $deleteData = json_decode($deleteResponse, true);

    // 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($deleteData['failures'] ?? 0));
    printf("소요 시간: %s ms\n", number_format($deleteData['took'] ?? 0));

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

    echo "\n";

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