#!/usr/bin/env python3
"""
Тестовый скрипт для проверки системы удаленных клиентов LogBoard
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""

import asyncio
import aiohttp
import json
import os
import subprocess
import time
from datetime import datetime

# Конфигурация теста
SERVER_URL = os.getenv('LOGBOARD_SERVER_URL', 'http://localhost:9001')
API_KEY = os.getenv('LOGBOARD_API_KEY', 'dev-key-123')
HOSTNAME = os.getenv('HOSTNAME', 'test-host')

async def test_server_availability():
    """Тестирование доступности сервера"""
    print("🔍 Проверка доступности сервера LogBoard...")
    
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(
                f"{SERVER_URL}/",
                timeout=aiohttp.ClientTimeout(total=10)
            ) as response:
                if response.status == 200:
                    print("✅ Сервер LogBoard доступен")
                    return True
                else:
                    print(f"❌ Сервер недоступен, статус: {response.status}")
                    return False
    except Exception as e:
        print(f"❌ Ошибка подключения к серверу: {e}")
        return False

async def test_remote_logs_endpoint():
    """Тестирование эндпоинта для удаленных логов"""
    print("📤 Тестирование отправки логов...")
    
    test_data = {
        "hostname": HOSTNAME,
        "container_name": "test-nginx",
        "logs": [
            f"{datetime.now().isoformat()} nginx: [info] Test log line 1",
            f"{datetime.now().isoformat()} nginx: [info] Test log line 2",
            f"{datetime.now().isoformat()} nginx: [error] Test error log",
            f"{datetime.now().isoformat()} nginx: [warn] Test warning log"
        ],
        "timestamp": datetime.now().isoformat()
    }
    
    headers = {
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json',
        'User-Agent': 'LogBoard-System-Test/1.0'
    }
    
    try:
        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{SERVER_URL}/api/logs/remote",
                json=test_data,
                headers=headers,
                timeout=aiohttp.ClientTimeout(total=30)
            ) as response:
                print(f"📊 Статус ответа: {response.status}")
                
                if response.status == 200:
                    result = await response.json()
                    print("✅ Логи успешно отправлены:")
                    print(f"   - Хост: {result.get('hostname')}")
                    print(f"   - Контейнер: {result.get('container_name')}")
                    print(f"   - Сообщение: {result.get('message')}")
                    print(f"   - Файл: {result.get('log_file')}")
                    return True
                else:
                    error_text = await response.text()
                    print(f"❌ Ошибка отправки логов: {response.status}")
                    print(f"   Ответ сервера: {error_text}")
                    return False
                    
    except Exception as e:
        print(f"❌ Ошибка при отправке логов: {e}")
        return False

def check_docker_services():
    """Проверка статуса Docker сервисов"""
    print("🐳 Проверка статуса Docker сервисов...")
    
    try:
        # Проверяем статус контейнеров
        result = subprocess.run(
            ['docker-compose', 'ps'],
            capture_output=True,
            text=True,
            cwd='.'
        )
        
        if result.returncode == 0:
            print("✅ Docker Compose сервисы:")
            print(result.stdout)
            return True
        else:
            print(f"❌ Ошибка проверки сервисов: {result.stderr}")
            return False
            
    except Exception as e:
        print(f"❌ Ошибка проверки Docker: {e}")
        return False

def check_log_files():
    """Проверка создания логовых файлов"""
    print("📁 Проверка логовых файлов...")
    
    log_dir = "logs/remote"
    if os.path.exists(log_dir):
        files = os.listdir(log_dir)
        if files:
            print(f"✅ Найдены логовые файлы в {log_dir}:")
            for file in files:
                file_path = os.path.join(log_dir, file)
                if os.path.isdir(file_path):
                    subfiles = os.listdir(file_path)
                    print(f"   📂 {file}/ ({len(subfiles)} файлов)")
                    for subfile in subfiles[:3]:  # Показываем первые 3 файла
                        print(f"      📄 {subfile}")
                    if len(subfiles) > 3:
                        print(f"      ... и еще {len(subfiles) - 3} файлов")
            return True
        else:
            print(f"⚠️  Директория {log_dir} пуста")
            return False
    else:
        print(f"❌ Директория {log_dir} не существует")
        return False

async def test_client_communication():
    """Тестирование связи с клиентом"""
    print("🔗 Тестирование связи с клиентом...")
    
    try:
        # Проверяем, запущен ли клиент
        result = subprocess.run(
            ['docker-compose', 'ps', 'logboard-client'],
            capture_output=True,
            text=True,
            cwd='.'
        )
        
        if 'Up' in result.stdout:
            print("✅ LogBoard клиент запущен")
            
            # Проверяем логи клиента
            logs_result = subprocess.run(
                ['docker-compose', 'logs', '--tail=10', 'logboard-client'],
                capture_output=True,
                text=True,
                cwd='.'
            )
            
            if logs_result.returncode == 0:
                print("📋 Последние логи клиента:")
                print(logs_result.stdout)
                return True
            else:
                print("⚠️  Не удалось получить логи клиента")
                return False
        else:
            print("❌ LogBoard клиент не запущен")
            return False
            
    except Exception as e:
        print(f"❌ Ошибка проверки клиента: {e}")
        return False

async def main():
    """Основная функция тестирования"""
    print("=" * 70)
    print("LogBoard Remote System - Полное тестирование")
    print("=" * 70)
    print(f"Сервер: {SERVER_URL}")
    print(f"API ключ: {API_KEY[:10]}..." if len(API_KEY) > 10 else f"API ключ: {API_KEY}")
    print(f"Хост: {HOSTNAME}")
    print()
    
    tests = []
    
    # Тест 1: Проверка Docker сервисов
    print("1️⃣ Проверка Docker сервисов...")
    docker_ok = check_docker_services()
    tests.append(("Docker сервисы", docker_ok))
    print()
    
    # Тест 2: Проверка доступности сервера
    print("2️⃣ Проверка доступности сервера...")
    server_ok = await test_server_availability()
    tests.append(("Доступность сервера", server_ok))
    print()
    
    if server_ok:
        # Тест 3: Отправка тестовых логов
        print("3️⃣ Отправка тестовых логов...")
        logs_ok = await test_remote_logs_endpoint()
        tests.append(("Отправка логов", logs_ok))
        print()
        
        # Тест 4: Проверка логовых файлов
        print("4️⃣ Проверка логовых файлов...")
        files_ok = check_log_files()
        tests.append(("Логовые файлы", files_ok))
        print()
        
        # Тест 5: Проверка клиента
        print("5️⃣ Проверка клиента...")
        client_ok = await test_client_communication()
        tests.append(("Связь с клиентом", client_ok))
        print()
    else:
        print("⚠️  Пропуск тестов 3-5 из-за недоступности сервера")
        tests.extend([
            ("Отправка логов", False),
            ("Логовые файлы", False),
            ("Связь с клиентом", False)
        ])
    
    # Результаты тестирования
    print("=" * 70)
    print("РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ")
    print("=" * 70)
    
    passed = 0
    total = len(tests)
    
    for test_name, result in tests:
        status = "✅ ПРОЙДЕН" if result else "❌ НЕ ПРОЙДЕН"
        print(f"{test_name:<20} {status}")
        if result:
            passed += 1
    
    print()
    print(f"Итого: {passed}/{total} тестов пройдено")
    
    if passed == total:
        print("🎉 Все тесты пройдены успешно!")
        print("   Система удаленных клиентов работает корректно.")
    elif passed >= total * 0.7:
        print("⚠️  Большинство тестов пройдено.")
        print("   Проверьте настройки для неудачных тестов.")
    else:
        print("❌ Много тестов не пройдено.")
        print("   Проверьте конфигурацию и запуск сервисов.")
    
    print()
    print("Полезные команды:")
    print("  make up          - Запуск всех сервисов")
    print("  make logs        - Просмотр логов")
    print("  make status      - Статус сервисов")
    print("  cd client && make test - Тестирование клиента")

if __name__ == "__main__":
    asyncio.run(main())
