use std::path::PathBuf;
use anyhow::{Context, bail};
use tokio::fs;
use crate::client::GitClient;
const REVIEW_BRANCH_FILE: &str = "gdot-review-branch";
pub async fn get_remote_owner_repo(git: &GitClient) -> anyhow::Result<(String, String)> {
let url = git.remote_url("origin").await?;
let path = if let Some(rest) = url.strip_prefix("git@") {
rest.split_once(':')
.map(|(_, path)| path.to_string())
.context("Invalid SSH remote URL")?
} else {
let segments: Vec<&str> = url.trim_end_matches('/').rsplit('/').take(2).collect();
if segments.len() < 2 {
bail!("Could not parse owner/repo from remote URL: {}", url);
}
format!("{}/{}", segments[1], segments[0])
};
let path = path.strip_suffix(".git").unwrap_or(&path);
let (owner, repo) = path
.split_once('/')
.context("Could not parse owner/repo from remote URL")?;
Ok((owner.to_string(), repo.to_string()))
}
pub async fn save_review_branch(git: &GitClient, branch: &str) -> anyhow::Result<()> {
let path = get_review_branch_path(git).await?;
fs::write(&path, branch).await?;
Ok(())
}
pub async fn load_review_branch(git: &GitClient) -> anyhow::Result<Option<String>> {
let path = get_review_branch_path(git).await?;
match fs::read_to_string(&path).await {
Ok(branch) => Ok(Some(branch.trim().to_string())),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
Err(e) => Err(e.into()),
}
}
pub async fn clear_review_branch(git: &GitClient) -> anyhow::Result<()> {
let path = get_review_branch_path(git).await?;
let _ = fs::remove_file(&path).await;
Ok(())
}
pub async fn push_for_review(
git: &GitClient,
branch: &str,
review_number: Option<i32>,
) -> anyhow::Result<Option<i32>> {
let refspec = match review_number {
Some(number) => format!("HEAD:refs/for/{}/{}", branch, number),
None => format!("HEAD:refs/for/{}", branch),
};
let stderr = git.push_refspec(&refspec).await?;
let result = stderr.lines().find_map(|line| {
let trimmed = line.strip_prefix("remote: ")?;
let rest = trimmed.strip_prefix("review #")?;
rest.split_whitespace().next()?.parse::<i32>().ok()
});
Ok(result)
}
async fn get_review_branch_path(git: &GitClient) -> anyhow::Result<PathBuf> {
Ok(git.git_dir().await?.join(REVIEW_BRANCH_FILE))
}