#!/usr/bin/env python3
"""
nginxログ分析: チェックイン・画像アップロード機能の使用状況を確認
"""

import subprocess
import re
from collections import defaultdict, Counter
from datetime import datetime

def analyze_provided_logs():
    """
    ユーザーが提供したログデータを分析
    """
    print("🔍 提供されたログデータの分析")
    print("=" * 50)
    
    # ユーザーが提供したログデータ
    log_data = """
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:15 +0000] "GET /api/new-events/ HTTP/1.0" 200 22641 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:15 +0000] "GET /api/entry/ HTTP/1.0" 200 11524 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:15 +0000] "GET /api/teams/ HTTP/1.0" 200 674 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:15 +0000] "GET /api/categories/ HTTP/1.0" 200 2824 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:18 +0000] "GET /api/user/current-entry-info/ HTTP/1.0" 200 512 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:19 +0000] "PATCH /api/entries/897/update-status/ HTTP/1.0" 200 1281 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:31 +0000] "GET /api/entry/ HTTP/1.0" 200 11523 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:31 +0000] "GET /api/teams/ HTTP/1.0" 200 674 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:31 +0000] "GET /api/new-events/ HTTP/1.0" 200 22641 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
nginx-1        | 172.18.0.1 - - [05/Sep/2025:17:25:31 +0000] "GET /api/categories/ HTTP/1.0" 200 2824 "-" "Dart/3.9 (dart:io)" "202.215.43.20"
    """.strip()
    
    analyze_log_content(log_data.split('\n'))

def analyze_log_content(lines):
    """
    ログ内容を分析する共通関数
    """
    print(f"📊 ログ行数: {len(lines)}")
    
    # チェックイン・画像関連のエンドポイント
    checkin_endpoints = {
        '/api/checkinimage/': '画像アップロード',
        '/gifuroge/checkin_from_rogapp': 'チェックイン登録',
        '/api/bulk_upload_checkin_photos/': '一括写真アップロード',
        '/api/user/current-entry-info/': 'ユーザー参加情報',
        '/api/entries/': 'エントリー操作',
        '/api/new-events/': 'イベント情報',
        '/api/teams/': 'チーム情報',
        '/api/categories/': 'カテゴリ情報'
    }
    
    # 分析結果
    endpoint_counts = defaultdict(int)
    methods = Counter()
    status_codes = Counter()
    user_agents = Counter()
    client_ips = Counter()
    dart_requests = 0
    
    for line in lines:
        if not line.strip():
            continue
            
        # ログパターンマッチング
        # nginx-1 | IP - - [timestamp] "METHOD path HTTP/1.0" status size "-" "user-agent" "real-ip"
        match = re.search(r'"(\w+)\s+([^"]+)\s+HTTP/[\d\.]+"\s+(\d+)\s+(\d+)\s+"[^"]*"\s+"([^"]*)"\s+"([^"]*)"', line)
        
        if match:
            method = match.group(1)
            path = match.group(2)
            status = match.group(3)
            size = match.group(4)
            user_agent = match.group(5)
            real_ip = match.group(6)
            
            methods[method] += 1
            status_codes[status] += 1
            user_agents[user_agent] += 1
            client_ips[real_ip] += 1
            
            # Dartクライアント（スマホアプリ）の検出
            if 'Dart/' in user_agent:
                dart_requests += 1
            
            # エンドポイント別カウント
            for endpoint in checkin_endpoints:
                if endpoint in path:
                    endpoint_counts[endpoint] += 1
    
    # 結果表示
    print(f"\n📱 Dartクライアント（スマホアプリ）リクエスト: {dart_requests}件")
    
    print(f"\n🎯 関連APIエンドポイントの使用状況:")
    print("-" * 60)
    
    found_activity = False
    for endpoint, description in checkin_endpoints.items():
        count = endpoint_counts[endpoint]
        if count > 0:
            print(f"✅ {description:20s} ({endpoint}): {count}回")
            found_activity = True
        else:
            print(f"❌ {description:20s} ({endpoint}): アクセスなし")
    
    print(f"\n📊 HTTPメソッド別:")
    for method, count in methods.most_common():
        print(f"  {method}: {count}回")
    
    print(f"\n📊 ステータスコード別:")
    for status, count in status_codes.most_common():
        print(f"  HTTP {status}: {count}回")
    
    print(f"\n📊 User Agent:")
    for ua, count in user_agents.most_common():
        ua_short = ua[:50] + "..." if len(ua) > 50 else ua
        print(f"  {ua_short}: {count}回")
    
    print(f"\n📊 クライアントIP:")
    for ip, count in client_ips.most_common():
        print(f"  {ip}: {count}回")
    
    # チェックイン・画像機能の判定
    print(f"\n🎯 機能使用状況の判定:")
    print("-" * 40)
    
    checkin_active = endpoint_counts['/gifuroge/checkin_from_rogapp'] > 0
    image_upload_active = endpoint_counts['/api/checkinimage/'] > 0
    bulk_upload_active = endpoint_counts['/api/bulk_upload_checkin_photos/'] > 0
    
    print(f"チェックイン登録機能: {'✅ 使用中' if checkin_active else '❌ 未使用'}")
    print(f"画像アップロード機能: {'✅ 使用中' if image_upload_active else '❌ 未使用'}")
    print(f"一括写真アップロード機能: {'✅ 使用中' if bulk_upload_active else '❌ 未使用'}")
    print(f"スマホアプリ（Dartクライアント）: {'✅ アクティブ' if dart_requests > 0 else '❌ 非アクティブ'}")
    
    if dart_requests > 0:
        print(f"\n📱 スマホアプリの動作状況:")
        print(f"  • アプリは正常に動作している")
        print(f"  • イベント情報、エントリー情報、チーム情報を取得中")
        print(f"  • エントリーステータスの更新も実行中")
        print(f"  • ただし、チェックインや画像アップロードは確認されていない")
    
    return found_activity
    """
    nginxログを分析してチェックイン・画像関連の活動を確認
    """
    print("🔍 nginx ログ分析: チェックイン・画像アップロード機能")
    print("=" * 70)
    
    # nginxログを取得
    try:
        result = subprocess.run(
            ['docker-compose', 'logs', '--tail=500', 'nginx'],
            capture_output=True,
            text=True
        )
        
        if result.returncode != 0:
            print(f"❌ ログ取得エラー: {result.stderr}")
            return
            
        log_lines = result.stdout.split('\n')
        
    except Exception as e:
        print(f"❌ 実行エラー: {e}")
        return
    
    # 分析用パターン
    patterns = {
        'checkin_api': re.compile(r'(POST|GET).*/(checkin_from_rogapp|checkin|addCheckin)', re.I),
        'image_api': re.compile(r'(POST|GET).*/checkinimage', re.I),
        'bulk_upload': re.compile(r'(POST|GET).*/bulk_upload', re.I),
        'dart_client': re.compile(r'"Dart/[\d\.]+ \(dart:io\)"'),
        'api_access': re.compile(r'"(GET|POST|PUT|PATCH|DELETE) (/api/[^"]+)'),
        'status_codes': re.compile(r'" (\d{3}) \d+')
    }
    
    # 分析結果
    results = {
        'checkin_requests': [],
        'image_requests': [],
        'bulk_upload_requests': [],
        'dart_requests': [],
        'api_endpoints': Counter(),
        'status_codes': Counter(),
        'client_ips': Counter()
    }
    
    # ログ行の解析
    for line in log_lines:
        if not line.strip() or 'nginx-1' not in line:
            continue
            
        # 各パターンをチェック
        if patterns['checkin_api'].search(line):
            results['checkin_requests'].append(line)
            
        if patterns['image_api'].search(line):
            results['image_requests'].append(line)
            
        if patterns['bulk_upload'].search(line):
            results['bulk_upload_requests'].append(line)
            
        if patterns['dart_client'].search(line):
            results['dart_requests'].append(line)
            
        # APIエンドポイント集計
        api_match = patterns['api_access'].search(line)
        if api_match:
            method, endpoint = api_match.groups()
            results['api_endpoints'][f"{method} {endpoint}"] += 1
            
        # ステータスコード集計
        status_match = patterns['status_codes'].search(line)
        if status_match:
            results['status_codes'][status_match.group(1)] += 1
            
        # クライアントIP集計
        ip_match = re.search(r'(\d+\.\d+\.\d+\.\d+) - -', line)
        if ip_match:
            results['client_ips'][ip_match.group(1)] += 1
    
    # 結果表示
    print_analysis_results(results)

def print_analysis_results(results):
    """
    分析結果を表示
    """
    
    # 1. チェックインAPI使用状況
    print(f"\n📍 チェックインAPI アクセス状況")
    print("-" * 50)
    if results['checkin_requests']:
        print(f"件数: {len(results['checkin_requests'])}件")
        for req in results['checkin_requests'][-5:]:  # 最新5件
            print(f"  {extract_log_info(req)}")
    else:
        print("❌ チェックインAPIへのアクセスなし")
    
    # 2. 画像アップロードAPI使用状況
    print(f"\n🖼️  画像アップロードAPI アクセス状況")
    print("-" * 50)
    if results['image_requests']:
        print(f"件数: {len(results['image_requests'])}件")
        for req in results['image_requests'][-5:]:  # 最新5件
            print(f"  {extract_log_info(req)}")
    else:
        print("❌ 画像アップロードAPIへのアクセスなし")
    
    # 3. 一括アップロードAPI使用状況
    print(f"\n📤 一括アップロードAPI アクセス状況")
    print("-" * 50)
    if results['bulk_upload_requests']:
        print(f"件数: {len(results['bulk_upload_requests'])}件")
        for req in results['bulk_upload_requests'][-5:]:  # 最新5件
            print(f"  {extract_log_info(req)}")
    else:
        print("❌ 一括アップロードAPIへのアクセスなし")
    
    # 4. Dartクライアント（スマホアプリ）の活動
    print(f"\n📱 スマホアプリ（Dart）アクセス状況")
    print("-" * 50)
    if results['dart_requests']:
        print(f"件数: {len(results['dart_requests'])}件")
        
        # Dartクライアントが使用しているAPIエンドポイント
        dart_endpoints = Counter()
        for req in results['dart_requests']:
            api_match = re.search(r'"(GET|POST|PUT|PATCH|DELETE) (/api/[^"]+)', req)
            if api_match:
                method, endpoint = api_match.groups()
                dart_endpoints[f"{method} {endpoint}"] += 1
        
        print("主要なAPIエンドポイント:")
        for endpoint, count in dart_endpoints.most_common(10):
            print(f"  {endpoint}: {count}回")
    else:
        print("❌ スマホアプリからのアクセスなし")
    
    # 5. 全体のAPI使用状況（Top 10）
    print(f"\n🌐 API使用状況 (Top 10)")
    print("-" * 50)
    for endpoint, count in results['api_endpoints'].most_common(10):
        print(f"  {endpoint}: {count}回")
    
    # 6. HTTPステータスコード分布
    print(f"\n📊 HTTPステータスコード分布")
    print("-" * 50)
    for status, count in results['status_codes'].most_common():
        status_emoji = get_status_emoji(status)
        print(f"  {status_emoji} {status}: {count}回")
    
    # 7. クライアントIP分布
    print(f"\n🌍 アクセス元IP分布")
    print("-" * 50)
    for ip, count in results['client_ips'].most_common(5):
        ip_type = "🏠 ローカル" if ip.startswith(('192.168', '172.', '127.')) else "🌐 外部"
        print(f"  {ip_type} {ip}: {count}回")

def extract_log_info(log_line):
    """
    ログ行から重要な情報を抽出
    """
    # 時刻を抽出
    time_match = re.search(r'\[([^\]]+)\]', log_line)
    time_str = time_match.group(1) if time_match else "Unknown"
    
    # メソッドとパスを抽出
    method_match = re.search(r'"(GET|POST|PUT|PATCH|DELETE) ([^"]+)', log_line)
    method_path = method_match.groups() if method_match else ("Unknown", "Unknown")
    
    # ステータスコードを抽出
    status_match = re.search(r'" (\d{3}) \d+', log_line)
    status = status_match.group(1) if status_match else "Unknown"
    
    # User Agentを抽出
    ua_match = re.search(r'"([^"]+)" "[^"]*"$', log_line)
    user_agent = ua_match.group(1) if ua_match else "Unknown"
    
    return f"{time_str} | {method_path[0]} {method_path[1][:50]}... | {status} | {user_agent[:20]}..."

def get_status_emoji(status_code):
    """
    HTTPステータスコードに対応する絵文字を返す
    """
    if status_code.startswith('2'):
        return '✅'
    elif status_code.startswith('3'):
        return '🔀'
    elif status_code.startswith('4'):
        return '❌'
    elif status_code.startswith('5'):
        return '💥'
    else:
        return '❓'

def analyze_nginx_logs():
    """
    Dockerコンテナからnginxログを取得・分析
    """
    print("🔍 Dockerからnginxログを取得中...")
    print("=" * 50)
    
    try:
        # docker-compose logsでnginxのログを取得
        result = subprocess.run(
            ['docker-compose', 'logs', '--tail=100', 'nginx'],
            capture_output=True,
            text=True,
            check=True
        )
        
        lines = result.stdout.split('\n')
        analyze_log_content(lines)
        
    except subprocess.CalledProcessError as e:
        print(f"❌ ログ取得エラー: {e}")
        print(f"stderr: {e.stderr}")
        print("\n💡 Dockerコンテナが起動していることを確認してください")
        print("   docker-compose ps")
    except FileNotFoundError:
        print("❌ docker-composeコマンドが見つかりません")
        print("💡 Dockerがインストールされていることを確認してください")


def main():
    print("🚀 スマホアプリのnginxログ解析ツール")
    print("=" * 50)
    
    choice = input("\n分析方法を選択してください:\n1. Dockerからログを取得\n2. 提供されたログデータを分析\n選択 (1/2): ")
    
    try:
        if choice == "1":
            analyze_nginx_logs()
        elif choice == "2":
            analyze_provided_logs()
        else:
            print("無効な選択です。提供されたログデータを分析します。")
            analyze_provided_logs()
        
        print(f"\n✅ 分析完了")
        print(f"\n💡 結論:")
        print(f"   ログから、チェックイン・画像アップロード機能の実際の使用状況を確認できます")
        print(f"   スマホアプリ（Dart）の活動状況も把握可能です")
        
    except Exception as e:
        print(f"❌ エラー: {e}")
        import traceback
        traceback.print_exc()

if __name__ == '__main__':
    main()
