"""Management operation routes: tenant, EFS, gitlab, jenkins, runner, db, setup, build."""
from __future__ import annotations

import sys
from pathlib import Path

from fastapi import APIRouter, HTTPException

_MONITOR_DIR = Path(__file__).resolve().parent.parent.parent.parent
if str(_MONITOR_DIR) not in sys.path:
    sys.path.insert(0, str(_MONITOR_DIR))

from gitlab_runner import GitLabRunner
from efs_runner import EFSSyncRunner
from tenant_runner import TenantRunner
from jenkins_runner import JenkinsRunner
from jenkins_trigger_runner import JenkinsTriggerRunner
from pipeline_runner_runner import PipelineRunnerRunner
from runner_trigger_runner import RunnerTriggerRunner
from db_runner import DbRunner
from setup_runner import SetupRunner
from build_runner import BuildRunner
from scripts_runner import RepoSetupRunner

from ..models import (
    TenantRequest,
    EFSSyncRequest,
    RepoSetupRequest,
    GitLabPushRequest,
    JenkinsSetupRequest,
    JenkinsTriggerRequest,
    RunnerSetupRequest,
    RunnerTriggerRequest,
    DBMigrateRequest,
    SetupInstallRequest,
    BuildRequest,
)
from ..session import get_or_create_session

router = APIRouter()


@router.post("/sessions/{session_id}/tenant/ensure")
async def ensure_tenant(session_id: str, req: TenantRequest):
    sess = get_or_create_session(session_id)
    if sess.tenant_status == "running":
        raise HTTPException(status_code=409, detail="Tenant operation already running")
    sess.tenant_logs = []
    sess.tenant_result = None
    sess.tenant_status = "running"
    r = TenantRunner()
    r.start(tenant_name=req.tenant_name)
    sess.tenant_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/efs/sync")
async def efs_sync(session_id: str, req: EFSSyncRequest):
    sess = get_or_create_session(session_id)
    if sess.efs_status == "running":
        raise HTTPException(status_code=409, detail="EFS sync already running")
    sess.efs_logs = []
    sess.efs_dest = None
    sess.efs_status = "running"
    r = EFSSyncRunner()
    r.start(project_slug=req.project_slug, efs_env=req.efs_env)
    sess.efs_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/scripts/generate")
async def scripts_generate(session_id: str, req: RepoSetupRequest):
    sess = get_or_create_session(session_id)
    if sess.scripts_status == "running":
        raise HTTPException(status_code=409, detail="Repo setup already running")
    sess.scripts_logs = []
    sess.scripts_dest = None
    sess.scripts_status = "running"
    r = RepoSetupRunner()
    r.start(project_dir=req.project_dir or None, project_slug=req.project_slug or None)
    sess.scripts_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/gitlab/push")
async def gitlab_push(session_id: str, req: GitLabPushRequest):
    sess = get_or_create_session(session_id)
    if sess.gitlab_status == "running":
        raise HTTPException(status_code=409, detail="GitLab push already running")
    sess.gitlab_logs = []
    sess.gitlab_url = None
    sess.gitlab_status = "running"
    r = GitLabRunner()
    r.start(
        project_dir=req.project_dir or None,
        project_slug=req.project_slug or None,
        org_code=req.org_code or None,
    )
    sess.gitlab_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/jenkins/setup")
async def jenkins_setup(session_id: str, req: JenkinsSetupRequest):
    sess = get_or_create_session(session_id)
    if sess.jenkins_status == "running":
        raise HTTPException(status_code=409, detail="Jenkins setup already running")
    sess.jenkins_logs = []
    sess.jenkins_url = None
    sess.jenkins_status = "running"
    r = JenkinsRunner()
    r.start(project_slug=req.project_slug, gitlab_url=req.gitlab_url)
    sess.jenkins_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/jenkins/trigger")
async def jenkins_trigger(session_id: str, req: JenkinsTriggerRequest):
    sess = get_or_create_session(session_id)
    if sess.jenkins_trig_status == "running":
        raise HTTPException(status_code=409, detail="Jenkins trigger already running")
    sess.jenkins_trig_logs = []
    sess.jenkins_trig_url = None
    sess.jenkins_trig_status = "running"
    r = JenkinsTriggerRunner()
    r.start(project_slug=req.project_slug, job=req.job)
    sess.jenkins_trig_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/runner/setup")
async def runner_setup(session_id: str, req: RunnerSetupRequest):
    sess = get_or_create_session(session_id)
    if sess.pr_status == "running":
        raise HTTPException(status_code=409, detail="Runner setup already running")
    sess.pr_logs = []
    sess.pr_url = None
    sess.pr_status = "running"
    r = PipelineRunnerRunner()
    r.start(project_slug=req.project_slug, gitlab_url=req.gitlab_url)
    sess.pr_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/runner/trigger")
async def runner_trigger(session_id: str, req: RunnerTriggerRequest):
    sess = get_or_create_session(session_id)
    if sess.pr_trig_status == "running":
        raise HTTPException(status_code=409, detail="Runner trigger already running")
    sess.pr_trig_logs = []
    sess.pr_trig_url = None
    sess.pr_trig_status = "running"
    r = RunnerTriggerRunner()
    r.start(project_slug=req.project_slug, job=req.job)
    sess.pr_trig_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/db/migrate")
async def db_migrate(session_id: str, req: DBMigrateRequest):
    sess = get_or_create_session(session_id)
    if sess.db_status == "running":
        raise HTTPException(status_code=409, detail="DB migration already running")
    sess.db_logs = []
    sess.db_status = "running"
    r = DbRunner()
    r.start(backend_dir=req.backend_dir or None, project_slug=req.project_slug or None)
    sess.db_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/setup/install")
async def setup_install(session_id: str, req: SetupInstallRequest):
    sess = get_or_create_session(session_id)
    if sess.setup_status == "running":
        raise HTTPException(status_code=409, detail="Setup already running")
    sess.setup_logs = []
    sess.setup_status = "running"
    r = SetupRunner()
    r.start(
        project_slug=req.project_slug or "",
        efs_env=req.efs_env or None,
        project_dir=req.project_dir or None,
    )
    sess.setup_runner = r
    return {"ok": True}


@router.post("/sessions/{session_id}/build/build")
async def build_project(session_id: str, req: BuildRequest):
    sess = get_or_create_session(session_id)
    if sess.build_status == "running":
        raise HTTPException(status_code=409, detail="Build already running")
    sess.build_logs = []
    sess.build_status = "running"
    r = BuildRunner()
    r.start(
        project_slug=req.project_slug or "",
        efs_env=req.efs_env or None,
        project_dir=req.project_dir or None,
    )
    sess.build_runner = r
    return {"ok": True}
