use crate::input::file::read_scraps;
use crate::mcp::json::scrap::ScrapKeyJson;
use crate::usecase::scrap::lookup_backlinks::usecase::LookupScrapBacklinksUsecase;
use rmcp::handler::server::wrapper::Parameters;
use rmcp::model::ErrorCode;
use rmcp::model::{CallToolResult, Content};
use rmcp::schemars::JsonSchema;
use rmcp::service::RequestContext;
use rmcp::{ErrorData, RoleServer};
use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Debug, Deserialize, JsonSchema)]
#[schemars(deny_unknown_fields)]
pub struct LookupScrapBacklinksRequest {
pub title: String,
pub ctx: Option<String>,
}
#[derive(Debug, Serialize)]
pub struct LookupScrapBacklinksResponse {
pub results: Vec<ScrapKeyJson>,
pub count: usize,
}
pub async fn lookup_scrap_backlinks(
scraps_dir: &Path,
exclude_dirs: &[std::path::PathBuf],
_context: RequestContext<RoleServer>,
Parameters(request): Parameters<LookupScrapBacklinksRequest>,
) -> Result<CallToolResult, ErrorData> {
let scraps = read_scraps::to_all_scraps(scraps_dir, exclude_dirs).map_err(|e| {
ErrorData::new(
ErrorCode(-32003),
format!("Failed to load scraps: {e}"),
None,
)
})?;
let get_backlinks_usecase = LookupScrapBacklinksUsecase::new();
let title = scraps_libs::model::title::Title::from(request.title.as_str());
let ctx = request
.ctx
.as_ref()
.map(|c| scraps_libs::model::context::Ctx::from(c.as_str()));
let results = get_backlinks_usecase
.execute(&scraps, &title, &ctx)
.map_err(|e| {
ErrorData::new(
ErrorCode(-32006),
format!("Get scrap backlinks failed: {e}"),
None,
)
})?;
let scrap_jsons: Vec<ScrapKeyJson> = results
.into_iter()
.map(|result| ScrapKeyJson {
title: result.title.to_string(),
ctx: result.ctx.map(|c| c.to_string()),
})
.collect();
let count = scrap_jsons.len();
let response = LookupScrapBacklinksResponse {
results: scrap_jsons,
count,
};
Ok(CallToolResult::success(vec![Content::text(
serde_json::to_string(&response).map_err(|e| {
ErrorData::new(
ErrorCode(-32007),
format!("JSON serialization failed: {e}"),
None,
)
})?,
)]))
}