//! Context wrapper for git tool handlers.
//!
//! Provides `GitToolCtx` which wraps `ToolContext` and adds git-domain operations.

use agent::ToolContext;
use git::GitDomain;
use models::projects::project;
use models::repos::repo;
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};

/// Wrapper around `ToolContext` providing git-domain operations for tool handlers.
#[derive(Clone)]
pub struct GitToolCtx {
    pub ctx: ToolContext,
}

impl GitToolCtx {
    pub fn new(ctx: ToolContext) -> Self {
        Self { ctx }
    }

    /// Opens a git repository by project name and repo name.
    pub async fn open_repo(&self, project_name: &str, repo_name: &str) -> Result<GitDomain, String> {
        let db = self.ctx.db();
        resolve_project_and_repo(db, project_name, repo_name)
            .await
            .and_then(|(_, path)| GitDomain::open(&path).map_err(|e| e.to_string()))
    }
}

/// Free helper to resolve project_id + storage_path from names. Used by registry.
async fn resolve_project_and_repo(
    db: &db::database::AppDatabase,
    project_name: &str,
    repo_name: &str,
) -> Result<(uuid::Uuid, String), String> {
    let project = project::Entity::find()
        .filter(project::Column::Name.eq(project_name))
        .one(db)
        .await
        .map_err(|e| format!("DB error looking up project '{}': {}", project_name, e))?
        .ok_or_else(|| format!("project '{}' not found", project_name))?;

    let repo_model = repo::Entity::find()
        .filter(repo::Column::Project.eq(project.id))
        .filter(repo::Column::RepoName.eq(repo_name))
        .one(db)
        .await
        .map_err(|e| format!("DB error looking up repo '{}/{}': {}", project_name, repo_name, e))?
        .ok_or_else(|| format!("repo '{}/{}' not found", project_name, repo_name))?;

    Ok((project.id, repo_model.storage_path))
}
