use std::sync::Arc;

use tonic::{Request, Response, Status};

use crate::{
    cmd::fork::ForkRepoParams,
    rpc::{error::to_status, proto as p, registry::RepoRegistry},
};

pub struct ForkServiceImpl {
    pub registry: Arc<RepoRegistry>,
}

#[tonic::async_trait]
impl p::fork_service_server::ForkService for ForkServiceImpl {
    async fn fork_bare(
        &self,
        req: Request<p::ForkBareRequest>,
    ) -> Result<Response<p::ForkBareResponse>, Status> {
        let inner = req.into_inner();
        let proto_params = inner.params.unwrap_or_default();

        let params = ForkRepoParams {
            namespace: proto_params.namespace,
            repo_name: proto_params.repo_name,
            default_branch: proto_params.default_branch,
            description: proto_params.description,
            enable_lfs: proto_params.enable_lfs,
        };

        let storage_root = inner.storage_root;
        let source_storage_path = inner.source_storage_path;

        let storage_path = ForkRepoParams::fork_bare(
            storage_root,
            source_storage_path,
            params,
        )
        .await
        .map_err(to_status)?;

        Ok(Response::new(p::ForkBareResponse { storage_path }))
    }
}
