//! The GitHub comments tap, the outbound half: a completed task that came from an issue
//! of one repository has its handoff posted back on that issue as a comment, once. The
//! host hands the tap only the handoffs it may read, under its ceiling, and records where
//! each was posted so a replay posts nothing twice. A post that fails costs only itself.
//! The tap holds no credential: the host puts the bearer token on the request.
//!
//! Config, JSON: `{"repo": "owner/name", "api": "https://api.github.com"}`; `api` is
//! optional and exists so a test can point the tap at a fake.

wit_bindgen::generate!({
    path: "../../crates/taps/wit",
    world: "tap",
});

use durable_memory::tap::memory::{completed, posted, Done};
use serde::Deserialize;
use wasi::http::outgoing_handler;
use wasi::http::types::{Fields, Method, OutgoingBody, OutgoingRequest, Scheme};
use wasi::io::streams::StreamError;

#[derive(Deserialize)]
struct Config {
    repo: String,
    #[serde(default = "github")]
    api: String,
}

fn github() -> String {
    "https://api.github.com".into()
}

#[derive(Deserialize)]
struct Comment {
    html_url: String,
}

/// `scheme`, `authority` and `path?query` of a URL.
fn split(url: &str) -> Result<(Scheme, String, String), String> {
    let (scheme, rest) = url
        .split_once("://")
        .ok_or_else(|| format!("{url:?} has no scheme"))?;
    let scheme = match scheme {
        "https" => Scheme::Https,
        "http" => Scheme::Http,
        other => Scheme::Other(other.to_string()),
    };
    let (authority, path) = match rest.split_once('/') {
        Some((a, p)) => (a.to_string(), format!("/{p}")),
        None => (rest.to_string(), "/".to_string()),
    };
    if authority.is_empty() {
        return Err(format!("{url:?} has no host"));
    }
    Ok((scheme, authority, path))
}

/// POST a JSON body to one URL; the status and the response text.
fn post(url: &str, json: &str) -> Result<(u16, String), String> {
    let (scheme, authority, path) = split(url)?;
    let headers = Fields::from_list(&[
        (
            "accept".to_string(),
            b"application/vnd.github+json".to_vec(),
        ),
        ("content-type".to_string(), b"application/json".to_vec()),
        ("user-agent".to_string(), b"durable-memory-tap/0.1".to_vec()),
    ])
    .map_err(|e| format!("headers: {e}"))?;
    let req = OutgoingRequest::new(headers);
    req.set_method(&Method::Post).map_err(|()| "method")?;
    req.set_scheme(Some(&scheme)).map_err(|()| "scheme")?;
    req.set_authority(Some(&authority))
        .map_err(|()| "authority")?;
    req.set_path_with_query(Some(&path)).map_err(|()| "path")?;
    let body = req.body().map_err(|()| "body")?;
    {
        let out = body.write().map_err(|()| "body stream")?;
        out.blocking_write_and_flush(json.as_bytes())
            .map_err(|e| format!("write: {e}"))?;
    }
    OutgoingBody::finish(body, None).map_err(|e| format!("finish: {e}"))?;
    let pending = outgoing_handler::handle(req, None).map_err(|e| format!("request: {e}"))?;
    pending.subscribe().block();
    let response = pending
        .get()
        .ok_or("no response")?
        .map_err(|()| "response taken twice")?
        .map_err(|e| format!("response: {e}"))?;
    let status = response.status();
    let body = response.consume().map_err(|()| "body")?;
    let stream = body.stream().map_err(|()| "stream")?;
    let mut bytes = Vec::new();
    loop {
        match stream.blocking_read(64 * 1024) {
            Ok(chunk) => bytes.extend(chunk),
            Err(StreamError::Closed) => break,
            Err(StreamError::LastOperationFailed(e)) => {
                return Err(format!("read: {}", e.to_debug_string()))
            }
        }
    }
    drop(stream);
    Ok((status, String::from_utf8_lossy(&bytes).into_owned()))
}

/// The issue number of an origin in this repository, `github:<repo>#<n>`.
fn issue_number(origin: &str, repo: &str) -> Option<u64> {
    origin
        .strip_prefix("github:")?
        .strip_prefix(repo)?
        .strip_prefix('#')?
        .parse()
        .ok()
}

/// The comment: the handoff as written, and a line saying where it came from.
fn comment(done: &Done) -> String {
    format!(
        "{}\n\n---\nPosted by the memory tap `github-comments`: the handoff `{}` of task `{}`.\n",
        done.text.trim_end(),
        done.handoff,
        done.id
    )
}

struct Component;

impl Guest for Component {
    fn run(config: String) -> Result<Report, String> {
        let config: Config = serde_json::from_str(&config).map_err(|e| format!("config: {e}"))?;
        if config.repo.split('/').filter(|s| !s.is_empty()).count() != 2
            || config.repo.contains("..")
        {
            return Err(format!("repo {:?} is not owner/name", config.repo));
        }
        let api = config.api.trim_end_matches('/');
        let mut report = Report {
            filed: 0,
            deduplicated: 0,
            proposed: 0,
            posted: 0,
            note: String::new(),
        };
        let (mut elsewhere, mut failed) = (0u32, Vec::new());
        for done in completed()? {
            let Some(number) = issue_number(&done.origin, &config.repo) else {
                elsewhere += 1;
                continue;
            };
            let url = format!("{api}/repos/{}/issues/{number}/comments", config.repo);
            let body = serde_json::json!({ "body": comment(&done) }).to_string();
            match post(&url, &body) {
                Ok((201, text)) => {
                    let to = serde_json::from_str::<Comment>(&text)
                        .map(|c| c.html_url)
                        .unwrap_or(url);
                    // the comment is up; a refusal to record it costs this one, not the run
                    match posted(&done.id, &to) {
                        Ok(()) => report.posted += 1,
                        Err(e) => failed.push(format!("#{number}: posted, not recorded: {e}")),
                    }
                }
                Ok((status, text)) => failed.push(format!(
                    "#{number}: {status} {}",
                    text.chars().take(120).collect::<String>()
                )),
                Err(e) => failed.push(format!("#{number}: {e}")),
            }
        }
        report.note = format!(
            "{}: {} handoffs posted, {elsewhere} done elsewhere{}",
            config.repo,
            report.posted,
            if failed.is_empty() {
                String::new()
            } else {
                format!(", {} failed: {}", failed.len(), failed.join("; "))
            }
        );
        Ok(report)
    }
}

export!(Component);
