#!/usr/bin/env python3
"""
Genesis MCP 統合サーバー - 使用FastMCP

使用方法:
    python -m genesis_mcp.genesis_server          # 標準モード
    python -m genesis_mcp.genesis_server --debug  # デバッグモード
"""

import argparse
import logging
import os
import sys
from pathlib import Path
from typing import Dict, Any, Optional

# プロジェクトパスを追加
project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))
sys.path.insert(0, str(project_root / "src"))

from mcp.server.fastmcp import FastMCP

# Genesisの可用性チェック
try:
    import genesis as gs
    GENESIS_AVAILABLE = True
except ImportError:
    GENESIS_AVAILABLE = False
    gs = None

# サービスモジュールの読み込み
GeminiCLIService = None
SimulationService = None
try:
    from .services.gemini_service import GeminiCLIService
    from .services.simulation import SimulationService
except ImportError:
    try:
        from genesis_mcp.services.gemini_service import GeminiCLIService
        from genesis_mcp.services.simulation import SimulationService
    except ImportError:
        pass

# FastMCPサーバー初期化
mcp = FastMCP("genesis-mcp")

# サービスインスタンス
gemini_service = None
simulation_service = None

def init_services():
    """サービス初期化"""
    global gemini_service, simulation_service
    try:
        if GeminiCLIService:
            gemini_service = GeminiCLIService()
        if SimulationService:
            simulation_service = SimulationService()
    except Exception as e:
        logging.warning(f"サービス初期化エラー: {e}")

# 初期化実行
init_services()

@mcp.tool()
def generate_simulation(description: str, use_llm: bool = True) -> str:
    """
    自然言語からGenesis Worldシミュレーションコードを生成

    Args:
        description: シミュレーション内容の説明
        use_llm: LLMを使用するかどうか
    """
    logging.info(f"シミュレーション生成: {description}")

    if use_llm and gemini_service:
        try:
            import asyncio
            system_prompt = """You are an expert Genesis World v0.3.3 code generator. Generate Python code that follows these requirements:

1. MANDATORY imports: import genesis as gs, import time, import math
2. Use gs.morphs.Sphere(radius=0.5) for spheres
3. Use gs.morphs.Box(size=(1.0, 1.0, 1.0)) for boxes
4. Set positions after scene.build()
5. Include simulation loop with time.sleep(0.01)

Return ONLY executable Python code without explanations."""

            user_prompt = f"Generate Genesis World code for: {description}"
            full_prompt = f"{system_prompt}\n\n{user_prompt}"

            response = asyncio.run(gemini_service.generate_text(full_prompt))

            if response:
                return f"🤖 GeminiCLI生成コード:\n```python\n{response}\n```"

        except Exception as e:
            logging.error(f"GeminiCLI生成エラー: {e}")

    # フォールバック: 固定テンプレート
    template_code = '''import genesis as gs
import time
import math

# Genesis初期化
gs.init(backend=gs.cpu)

# シーン作成
scene = gs.Scene(show_viewer=True)

# 球体オブジェクト作成
sphere = scene.add_entity(gs.morphs.Sphere(radius=0.5))

# シーンビルド
scene.build()

# 位置設定
sphere.set_pos((0, 0, 2))

print("🎯 シミュレーション開始")

# シミュレーション実行
for i in range(1000):
    scene.step()
    if i % 50 == 0:
        print(f"Step: {i}")
        time.sleep(0.01)

print("✅ シミュレーション完了")'''

    return f"📝 テンプレートコード:\n```python\n{template_code}\n```"

@mcp.tool()
def execute_simulation(code: str, show_gui: bool = True) -> str:
    """
    Genesis Worldシミュレーションを実行

    Args:
        code: 実行するGenesis Worldコード
        show_gui: GUIを表示するかどうか
    """
    logging.info("シミュレーション実行開始")

    if not GENESIS_AVAILABLE:
        return "❌ Genesis Worldがインストールされていません。シミュレーション実行できません。"

    try:
        # 実行環境設定
        if not show_gui:
            os.environ["GENESIS_SHOW_VIEWER"] = "false"

        # コード実行
        exec_globals = {
            '__name__': '__main__',
            '__builtins__': __builtins__,
            'gs': gs,
            'time': __import__('time'),
            'math': __import__('math'),
            'print': print
        }

        exec(code, exec_globals)

        return "✅ シミュレーション実行完了"

    except Exception as e:
        error_msg = f"❌ 実行エラー: {e}"
        logging.error(error_msg)
        return error_msg

@mcp.tool()
def get_templates(category: str = "basic") -> str:
    """
    Genesis Worldテンプレート一覧を取得

    Args:
        category: テンプレートカテゴリ (basic/physics/advanced)
    """
    templates = {
        "basic": {
            "falling_sphere": "球体落下シミュレーション",
            "bouncing_ball": "弾むボールシミュレーション",
            "rolling_sphere": "転がる球体シミュレーション"
        },
        "physics": {
            "collision": "衝突シミュレーション",
            "friction": "摩擦力シミュレーション",
            "gravity": "重力シミュレーション"
        },
        "advanced": {
            "multi_body": "複数オブジェクトシミュレーション",
            "constraint": "制約付きシミュレーション"
        }
    }

    category_templates = templates.get(category, templates["basic"])

    template_list = "\n".join([
        f"- **{name}**: {desc}"
        for name, desc in category_templates.items()
    ])

    return f"📋 {category}カテゴリのテンプレート:\n{template_list}"

@mcp.tool()
def check_environment() -> str:
    """Genesis環境とサービス状態をチェック"""
    status = {}

    # Genesis World チェック
    if GENESIS_AVAILABLE:
        try:
            gs.init()
            status["genesis"] = "✅ 利用可能"
        except Exception as e:
            status["genesis"] = f"❌ エラー: {e}"
    else:
        status["genesis"] = "❌ インストールされていません"

    # GeminiCLI サービスチェック
    if gemini_service:
        try:
            import asyncio
            test_response = asyncio.run(gemini_service.generate_text("test"))
            status["gemini"] = "✅ 利用可能" if test_response else "❌ 応答なし"
        except Exception as e:
            status["gemini"] = f"❌ エラー: {e}"
    else:
        status["gemini"] = "❌ 初期化されていません"

    # 環境変数チェック
    gemini_key = os.environ.get("GEMINI_API_KEY")
    status["gemini_key"] = "✅ 設定済み" if gemini_key else "❌ 未設定"

    status_text = "\n".join([
        f"**{name}**: {status_val}"
        for name, status_val in status.items()
    ])

    return f"🔍 環境チェック結果:\n{status_text}"

def main():
    parser = argparse.ArgumentParser(
        description="Genesis MCP 統合サーバー",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )

    parser.add_argument("-d", "--debug", action="store_true",
                       help="デバッグモード")

    args = parser.parse_args()

    if args.debug:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    # FastMCPサーバーを起動
    mcp.run()

if __name__ == "__main__":
    main()