#!/usr/bin/env php
<?php
/**
 * ptyMysqlInfo
 *
 * MySQL 서버 정보 조회 도구
 * 설정 파일: ~/.ptyMysqlConfig.ini
 *
 * Usage: ./ptyMysqlInfo [options]
 */

namespace platyFramework;

require_once __DIR__ . '/ptyLibrary_PHP/cli/ptyCliOptionParser.php';
require_once __DIR__ . '/ptyLibrary_PHP/mysql/ptyMysqlConfig.php';

// 인자 파싱
$parsed = ptyCliOptionParser::parse($argv);
$positionalArgs = $parsed['positional'];
$options = $parsed['options'];
$mysqlSection = $options['mysql'] ?? 'default';

// 도움말
if (isset($options['help'])) {
    echo "사용법: {$argv[0]} [옵션]\n";
    echo "\n";
    echo "옵션:\n";
    echo "  --mysql=섹션명      INI 파일 섹션 (기본값: default)\n";
    echo "  --help              도움말 출력\n";
    echo "\n";
    echo "예시:\n";
    echo "  {$argv[0]}                        # default 섹션 사용\n";
    echo "  {$argv[0]} --mysql=production     # production 섹션 사용\n";
    echo "\n";
    echo "설정 파일: ~/.ptyMysqlConfig.ini\n";
    echo ptyMysqlConfig::getConfigExample() . "\n";
    exit(0);
}

// ANSI 색상 코드
$RED = "\033[1;31m";
$GREEN = "\033[1;32m";
$YELLOW = "\033[1;33m";
$CYAN = "\033[1;36m";
$MAGENTA = "\033[1;35m";
$RESET = "\033[0m";

// 바이트를 읽기 쉬운 형식으로 변환
function formatBytes($bytes) {
    $bytes = (int)$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';
    }
}

// 한글 포함 문자열 패딩 (터미널 출력용)
function padLabel($str, $width) {
    $strWidth = mb_strwidth($str);
    $padding = $width - $strWidth;
    return $str . str_repeat(' ', max(0, $padding));
}

// 초를 읽기 쉬운 형식으로 변환
function formatUptime($seconds) {
    $days = floor($seconds / 86400);
    $hours = floor(($seconds % 86400) / 3600);
    $minutes = floor(($seconds % 3600) / 60);
    $secs = $seconds % 60;

    $parts = [];
    if ($days > 0) $parts[] = "{$days}일";
    if ($hours > 0) $parts[] = "{$hours}시간";
    if ($minutes > 0) $parts[] = "{$minutes}분";
    if ($secs > 0 || empty($parts)) $parts[] = "{$secs}초";

    return implode(' ', $parts);
}

try {
    // MySQL 연결
    $conn = ptyMysqlConfig::connect($mysqlSection);
    $connection = $conn['connection'];
    $config = $conn['config'];

    echo "\n";
    echo "{$CYAN}╔══════════════════════════════════════════════════════════════════╗{$RESET}\n";
    echo "{$CYAN}║                      MySQL 서버 정보                             ║{$RESET}\n";
    echo "{$CYAN}╚══════════════════════════════════════════════════════════════════╝{$RESET}\n";
    echo "\n";

    // ============================================
    // 1. 연결 정보
    // ============================================
    echo "{$YELLOW}[ 연결 정보 ]{$RESET}\n";
    echo str_repeat("-", 60) . "\n";
    echo "  Host      : {$config['host']}\n";
    echo "  User      : {$config['username']}\n";
    echo "  Section   : $mysqlSection\n";
    echo "  Charset   : {$config['charset']}\n";
    echo "\n";

    // ============================================
    // 2. 서버 정보
    // ============================================
    echo "{$YELLOW}[ 서버 정보 ]{$RESET}\n";
    echo str_repeat("-", 60) . "\n";

    // 버전
    $result = mysqli_query($connection, "SELECT VERSION() as version");
    $row = mysqli_fetch_assoc($result);
    echo "  " . padLabel("Version", 18) . ": {$row['version']}\n";

    // 주요 변수들
    $variables = [
        'version_comment' => '버전 설명',
        'hostname' => '호스트명',
        'port' => '포트',
        'socket' => '소켓',
        'datadir' => '데이터 디렉토리',
        'basedir' => '설치 디렉토리',
        'character_set_server' => '서버 문자셋',
        'collation_server' => '서버 Collation',
        'max_connections' => '최대 연결 수',
        'max_allowed_packet' => '최대 패킷 크기',
        'innodb_buffer_pool_size' => 'InnoDB 버퍼 풀',
    ];

    $result = mysqli_query($connection, "SHOW VARIABLES WHERE Variable_name IN ('" . implode("','", array_keys($variables)) . "')");
    $varValues = [];
    while ($row = mysqli_fetch_assoc($result)) {
        $varValues[$row['Variable_name']] = $row['Value'];
    }

    foreach ($variables as $varName => $label) {
        if (isset($varValues[$varName])) {
            $value = $varValues[$varName];
            // 바이트 값 포맷팅
            if (in_array($varName, ['max_allowed_packet', 'innodb_buffer_pool_size'])) {
                $value = formatBytes($value);
            }
            echo "  " . padLabel($label, 18) . ": $value\n";
        }
    }
    echo "\n";

    // ============================================
    // 3. 서버 상태
    // ============================================
    echo "{$YELLOW}[ 서버 상태 ]{$RESET}\n";
    echo str_repeat("-", 60) . "\n";

    $statusVars = [
        'Uptime' => 'Uptime',
        'Threads_connected' => '현재 연결 수',
        'Threads_running' => '실행 중 쓰레드',
        'Questions' => '총 쿼리 수',
        'Slow_queries' => '슬로우 쿼리',
        'Opens' => '열린 테이블',
        'Connections' => '총 연결 시도',
        'Aborted_connects' => '실패한 연결',
        'Bytes_received' => '수신 바이트',
        'Bytes_sent' => '송신 바이트',
    ];

    $result = mysqli_query($connection, "SHOW GLOBAL STATUS WHERE Variable_name IN ('" . implode("','", array_keys($statusVars)) . "')");
    $statusValues = [];
    while ($row = mysqli_fetch_assoc($result)) {
        $statusValues[$row['Variable_name']] = $row['Value'];
    }

    foreach ($statusVars as $varName => $label) {
        if (isset($statusValues[$varName])) {
            $value = $statusValues[$varName];
            if ($varName === 'Uptime') {
                $value = formatUptime($value);
            } elseif (in_array($varName, ['Bytes_received', 'Bytes_sent'])) {
                $value = formatBytes($value);
            } else {
                $value = number_format($value);
            }
            echo "  " . padLabel($label, 18) . ": $value\n";
        }
    }
    echo "\n";

    // ============================================
    // 4. 데이터베이스 목록
    // ============================================
    echo "{$YELLOW}[ 데이터베이스 목록 ]{$RESET}\n";
    echo str_repeat("-", 60) . "\n";

    $systemDbs = ['information_schema', 'performance_schema', 'mysql', 'sys'];

    $result = mysqli_query($connection, "SHOW DATABASES");
    $databases = [];
    while ($row = mysqli_fetch_row($result)) {
        $databases[] = $row[0];
    }

    $userDbCount = 0;
    $systemDbCount = 0;

    printf("  {$CYAN}%-30s %10s %10s{$RESET}\n", "Database", "Tables", "Size");
    echo "  " . str_repeat("-", 52) . "\n";

    foreach ($databases as $dbName) {
        $isSystem = in_array($dbName, $systemDbs);

        if ($isSystem) {
            $systemDbCount++;
        } else {
            $userDbCount++;
        }

        // 테이블 수 조회
        $tableResult = mysqli_query($connection, "SELECT COUNT(*) as cnt FROM information_schema.tables WHERE table_schema = '$dbName'");
        $tableRow = mysqli_fetch_assoc($tableResult);
        $tableCount = $tableRow['cnt'];

        // DB 크기 조회
        $sizeResult = mysqli_query($connection, "SELECT SUM(data_length + index_length) as size FROM information_schema.tables WHERE table_schema = '$dbName'");
        $sizeRow = mysqli_fetch_assoc($sizeResult);
        $dbSize = $sizeRow['size'] ? formatBytes($sizeRow['size']) : '0 bytes';

        $color = $isSystem ? $MAGENTA : $GREEN;
        $marker = $isSystem ? '[SYS]' : '';

        printf("  {$color}%-30s %10s %10s{$RESET} %s\n", $dbName, $tableCount, $dbSize, $marker);
    }

    echo "\n";
    echo "  총 데이터베이스: " . count($databases) . "개 (사용자: {$userDbCount}, 시스템: {$systemDbCount})\n";
    echo "\n";

    // ============================================
    // 5. 사용자 목록
    // ============================================
    echo "{$YELLOW}[ 사용자 목록 ]{$RESET}\n";
    echo str_repeat("-", 100) . "\n";

    $result = mysqli_query($connection, "SELECT User, Host, account_locked, password_expired,
        IF(authentication_string = '' OR authentication_string IS NULL, 'NO', 'YES') as has_password
        FROM mysql.user ORDER BY User, Host");

    if ($result) {
        printf("  {$CYAN}%-20s %-25s %-12s %-12s %-10s{$RESET}\n",
            "User", "Host", "Locked", "PW Expired", "Has PW");
        echo "  " . str_repeat("-", 82) . "\n";

        $userCount = 0;
        while ($row = mysqli_fetch_assoc($result)) {
            $userCount++;
            $locked = $row['account_locked'] ?? 'N';
            $expired = $row['password_expired'] ?? 'N';
            $hasPw = $row['has_password'] ?? '-';

            $lockedColor = ($locked === 'Y') ? $RED : $GREEN;
            $expiredColor = ($expired === 'Y') ? $RED : $GREEN;

            printf("  %-20s %-25s {$lockedColor}%-12s{$RESET} {$expiredColor}%-12s{$RESET} %-10s\n",
                substr($row['User'], 0, 20),
                substr($row['Host'], 0, 25),
                $locked,
                $expired,
                $hasPw
            );
        }
        echo "\n";
        echo "  총 사용자: {$userCount}명\n";
    } else {
        echo "  (mysql.user 테이블 접근 권한 없음)\n";
    }
    echo "\n";

    // ============================================
    // 6. 현재 프로세스 목록
    // ============================================
    echo "{$YELLOW}[ 현재 프로세스 (FULL PROCESSLIST) ]{$RESET}\n";
    echo str_repeat("-", 100) . "\n";

    $result = mysqli_query($connection, "SHOW FULL PROCESSLIST");
    printf("  {$CYAN}%-7s %-12s %-20s %-12s %-6s %-10s %-20s{$RESET}\n",
        "ID", "User", "Host", "DB", "Time", "Command", "State");
    echo "  " . str_repeat("-", 96) . "\n";

    $processCount = 0;
    while ($row = mysqli_fetch_assoc($result)) {
        $processCount++;
        $host = substr($row['Host'], 0, 20);
        $db = $row['db'] ?? '-';
        $state = $row['State'] ?? '-';
        $command = $row['Command'] ?? '-';
        $info = $row['Info'] ?? null;

        printf("  %-7s %-12s %-20s %-12s %-6s %-10s %-20s\n",
            $row['Id'],
            substr($row['User'], 0, 12),
            $host,
            substr($db, 0, 12),
            $row['Time'] . 's',
            substr($command, 0, 10),
            substr($state, 0, 20)
        );

        // 실행 중인 쿼리가 있으면 표시
        if ($info && $command !== 'Sleep') {
            $infoTrimmed = trim(preg_replace('/\s+/', ' ', $info));
            if (strlen($infoTrimmed) > 80) {
                $infoTrimmed = substr($infoTrimmed, 0, 77) . '...';
            }
            echo "          {$MAGENTA}└─ Query: {$infoTrimmed}{$RESET}\n";
        }
    }
    echo "\n";
    echo "  총 프로세스: {$processCount}개\n";
    echo "\n";

    // ============================================
    // 7. InnoDB 상태
    // ============================================
    echo "{$YELLOW}[ InnoDB 상태 ]{$RESET}\n";
    echo str_repeat("-", 60) . "\n";

    $innodbVars = [
        'Innodb_buffer_pool_pages_total' => '버퍼 풀 페이지 (전체)',
        'Innodb_buffer_pool_pages_free' => '버퍼 풀 페이지 (여유)',
        'Innodb_buffer_pool_pages_dirty' => '버퍼 풀 페이지 (더티)',
        'Innodb_buffer_pool_read_requests' => '버퍼 풀 읽기 요청',
        'Innodb_buffer_pool_reads' => '디스크 읽기',
        'Innodb_rows_read' => '읽은 행 수',
        'Innodb_rows_inserted' => '삽입된 행 수',
        'Innodb_rows_updated' => '업데이트된 행 수',
        'Innodb_rows_deleted' => '삭제된 행 수',
    ];

    $result = mysqli_query($connection, "SHOW GLOBAL STATUS WHERE Variable_name LIKE 'Innodb%'");
    $innodbValues = [];
    while ($row = mysqli_fetch_assoc($result)) {
        $innodbValues[$row['Variable_name']] = $row['Value'];
    }

    foreach ($innodbVars as $varName => $label) {
        if (isset($innodbValues[$varName])) {
            echo "  " . padLabel($label, 26) . ": " . number_format($innodbValues[$varName]) . "\n";
        }
    }

    // 버퍼 풀 히트율 계산
    if (isset($innodbValues['Innodb_buffer_pool_read_requests']) && isset($innodbValues['Innodb_buffer_pool_reads'])) {
        $requests = (int)$innodbValues['Innodb_buffer_pool_read_requests'];
        $reads = (int)$innodbValues['Innodb_buffer_pool_reads'];
        if ($requests > 0) {
            $hitRate = (($requests - $reads) / $requests) * 100;
            echo "  " . padLabel("버퍼 풀 히트율", 26) . ": " . sprintf("%.2f%%", $hitRate) . "\n";
        }
    }
    echo "\n";

    // ============================================
    // 8. 주요 설정 변수
    // ============================================
    echo "{$YELLOW}[ 주요 설정 변수 ]{$RESET}\n";
    echo str_repeat("-", 60) . "\n";

    $moreVars = [
        'query_cache_size' => '쿼리 캐시 크기',
        'query_cache_type' => '쿼리 캐시 타입',
        'tmp_table_size' => '임시 테이블 크기',
        'max_heap_table_size' => '힙 테이블 크기',
        'sort_buffer_size' => '정렬 버퍼',
        'read_buffer_size' => '읽기 버퍼',
        'join_buffer_size' => '조인 버퍼',
        'thread_cache_size' => '쓰레드 캐시',
        'table_open_cache' => '테이블 캐시',
        'slow_query_log' => '슬로우 쿼리 로그',
        'long_query_time' => '슬로우 쿼리 기준(초)',
        'log_bin' => '바이너리 로그',
    ];

    $bytesVars = ['query_cache_size', 'tmp_table_size', 'max_heap_table_size', 'sort_buffer_size', 'read_buffer_size', 'join_buffer_size'];

    $result = mysqli_query($connection, "SHOW VARIABLES WHERE Variable_name IN ('" . implode("','", array_keys($moreVars)) . "')");
    while ($row = mysqli_fetch_assoc($result)) {
        $varName = $row['Variable_name'];
        $label = $moreVars[$varName] ?? $varName;
        $value = $row['Value'];

        // 바이트 값 포맷팅
        if (in_array($varName, $bytesVars)) {
            $value = formatBytes($value);
        }

        $displayLabel = "$label ($varName)";
        echo "  " . padLabel($displayLabel, 42) . ": $value\n";
    }
    echo "\n";

    mysqli_close($connection);

    echo "{$CYAN}══════════════════════════════════════════════════════════════════{$RESET}\n";
    echo "\n";

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