import os
import logging
import subprocess

logger = logging.getLogger('gaze')

# Path to the MCP docker-compose projects, relative to the main app file.
MCP_TOOLS_DIR         = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'tools')
MCP_COMPOSE_DIR       = os.path.join(MCP_TOOLS_DIR, 'danbooru-mcp')
MCP_REPO_URL          = 'https://git.liveaodh.com/aodhan/danbooru-mcp'
CHAR_MCP_COMPOSE_DIR  = os.path.join(MCP_TOOLS_DIR, 'character-mcp')
CHAR_MCP_REPO_URL     = 'https://git.liveaodh.com/aodhan/character-mcp.git'


def _ensure_mcp_repo():
    """Clone or update the danbooru-mcp source repository inside tools/.

    - If ``tools/danbooru-mcp/`` does not exist, clone from MCP_REPO_URL.
    - If it already exists, run ``git pull`` to fetch the latest changes.
    Errors are non-fatal.
    """
    os.makedirs(MCP_TOOLS_DIR, exist_ok=True)
    try:
        if not os.path.isdir(MCP_COMPOSE_DIR):
            logger.info('Cloning danbooru-mcp from %s …', MCP_REPO_URL)
            subprocess.run(
                ['git', 'clone', MCP_REPO_URL, MCP_COMPOSE_DIR],
                timeout=120, check=True,
            )
            logger.info('danbooru-mcp cloned successfully.')
        else:
            logger.info('Updating danbooru-mcp via git pull …')
            subprocess.run(
                ['git', 'pull'],
                cwd=MCP_COMPOSE_DIR,
                timeout=60, check=True,
            )
            logger.info('danbooru-mcp updated.')
    except FileNotFoundError:
        logger.warning('git not found on PATH — danbooru-mcp repo will not be cloned/updated.')
    except subprocess.CalledProcessError as e:
        logger.warning('git operation failed for danbooru-mcp: %s', e)
    except subprocess.TimeoutExpired:
        logger.warning('git timed out while cloning/updating danbooru-mcp.')
    except Exception as e:
        logger.warning('Could not clone/update danbooru-mcp repo: %s', e)


def ensure_mcp_server_running():
    """Ensure the danbooru-mcp repo is present/up-to-date, then start the
    Docker container if it is not already running.

    Uses ``docker compose up -d`` so the image is built automatically on first
    run.  Errors are non-fatal — the app will still start even if Docker is
    unavailable.

    Skipped when ``SKIP_MCP_AUTOSTART=true`` (set by docker-compose, where the
    danbooru-mcp service is managed by compose instead).
    """
    if os.environ.get('SKIP_MCP_AUTOSTART', '').lower() == 'true':
        logger.info('SKIP_MCP_AUTOSTART set — skipping danbooru-mcp auto-start.')
        return
    _ensure_mcp_repo()
    try:
        result = subprocess.run(
            ['docker', 'ps', '--filter', 'name=danbooru-mcp', '--format', '{{.Names}}'],
            capture_output=True, text=True, timeout=10,
        )
        if 'danbooru-mcp' in result.stdout:
            logger.info('danbooru-mcp container already running.')
            return
        # Container not running — start it via docker compose
        logger.info('Starting danbooru-mcp container via docker compose …')
        subprocess.run(
            ['docker', 'compose', 'up', '-d'],
            cwd=MCP_COMPOSE_DIR,
            timeout=120,
        )
        logger.info('danbooru-mcp container started.')
    except FileNotFoundError:
        logger.warning('docker not found on PATH — danbooru-mcp will not be started automatically.')
    except subprocess.TimeoutExpired:
        logger.warning('docker timed out while starting danbooru-mcp.')
    except Exception as e:
        logger.warning('Could not ensure danbooru-mcp is running: %s', e)


def _ensure_character_mcp_repo():
    """Clone or update the character-mcp source repository inside tools/.

    - If ``tools/character-mcp/`` does not exist, clone from CHAR_MCP_REPO_URL.
    - If it already exists, run ``git pull`` to fetch the latest changes.
    Errors are non-fatal.
    """
    os.makedirs(MCP_TOOLS_DIR, exist_ok=True)
    try:
        if not os.path.isdir(CHAR_MCP_COMPOSE_DIR):
            logger.info('Cloning character-mcp from %s …', CHAR_MCP_REPO_URL)
            subprocess.run(
                ['git', 'clone', CHAR_MCP_REPO_URL, CHAR_MCP_COMPOSE_DIR],
                timeout=120, check=True,
            )
            logger.info('character-mcp cloned successfully.')
        else:
            logger.info('Updating character-mcp via git pull …')
            subprocess.run(
                ['git', 'pull'],
                cwd=CHAR_MCP_COMPOSE_DIR,
                timeout=60, check=True,
            )
            logger.info('character-mcp updated.')
    except FileNotFoundError:
        logger.warning('git not found on PATH — character-mcp repo will not be cloned/updated.')
    except subprocess.CalledProcessError as e:
        logger.warning('git operation failed for character-mcp: %s', e)
    except subprocess.TimeoutExpired:
        logger.warning('git timed out while cloning/updating character-mcp.')
    except Exception as e:
        logger.warning('Could not clone/update character-mcp repo: %s', e)


def ensure_character_mcp_server_running():
    """Ensure the character-mcp repo is present/up-to-date, then start the
    Docker container if it is not already running.

    Uses ``docker compose up -d`` so the image is built automatically on first
    run.  Errors are non-fatal — the app will still start even if Docker is
    unavailable.

    Skipped when ``SKIP_MCP_AUTOSTART=true`` (set by docker-compose, where the
    character-mcp service is managed by compose instead).
    """
    if os.environ.get('SKIP_MCP_AUTOSTART', '').lower() == 'true':
        logger.info('SKIP_MCP_AUTOSTART set — skipping character-mcp auto-start.')
        return
    _ensure_character_mcp_repo()
    try:
        result = subprocess.run(
            ['docker', 'ps', '--filter', 'name=character-mcp', '--format', '{{.Names}}'],
            capture_output=True, text=True, timeout=10,
        )
        if 'character-mcp' in result.stdout:
            logger.info('character-mcp container already running.')
            return
        # Container not running — start it via docker compose
        logger.info('Starting character-mcp container via docker compose …')
        subprocess.run(
            ['docker', 'compose', 'up', '-d'],
            cwd=CHAR_MCP_COMPOSE_DIR,
            timeout=120,
        )
        logger.info('character-mcp container started.')
    except FileNotFoundError:
        logger.warning('docker not found on PATH — character-mcp will not be started automatically.')
    except subprocess.TimeoutExpired:
        logger.warning('docker timed out while starting character-mcp.')
    except Exception as e:
        logger.warning('Could not ensure character-mcp is running: %s', e)
