use forge::signal::compactor;
use once_cell::sync::Lazy;
use regex::Regex;

static ENTERING_RE: Lazy<Regex> =
    Lazy::new(|| Regex::new(r"(?m)^make\[\d+\]: (Entering|Leaving) directory '[^']+'\n?").unwrap());
static NOTHING_TO_DO_RE: Lazy<Regex> =
    Lazy::new(|| Regex::new(r"(?m)^make\[\d+\]: Nothing to be done[^\n]+\n?").unwrap());

// ── make ──────────────────────────────────────────────────────────────────────

pub fn compress_make(raw: &str, exit_code: i32) -> String {
    let cleaned = compactor::normalise(raw);
    let s = ENTERING_RE.replace_all(&cleaned, "");
    let s = NOTHING_TO_DO_RE.replace_all(&s, "");
    if exit_code == 0 {
        // On success, keep only non-compile-command lines
        // (strip long gcc/clang invocations that are pure noise)
        let out: Vec<&str> = s
            .lines()
            .filter(|l| {
                !l.trim_start().starts_with("gcc ")
                    && !l.trim_start().starts_with("g++ ")
                    && !l.trim_start().starts_with("clang ")
                    && !l.trim_start().starts_with("clang++ ")
                    && !l.trim_start().starts_with("cc ")
                    && !l.trim_start().starts_with("ar ")
            })
            .collect();
        return compactor::collapse_blanks(&out.join("\n"));
    }
    compactor::collapse_blanks(&s)
}

// ── cmake ─────────────────────────────────────────────────────────────────────

pub fn compress_cmake(raw: &str) -> String {
    let cleaned = compactor::normalise(raw);
    // Strip "-- Checking…" configure test lines
    let out: Vec<&str> = cleaned
        .lines()
        .filter(|l| {
            !l.starts_with("-- Checking")
                && !l.starts_with("-- Performing")
                && !l.starts_with("-- Looking")
                && !l.starts_with("-- Detecting")
        })
        .collect();
    compactor::collapse_blanks(&out.join("\n"))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn make_strips_entering_leaving() {
        let raw = "make[1]: Entering directory '/src'\ngcc -o foo foo.c\nmake[1]: Leaving directory '/src'\n";
        let out = compress_make(raw, 0);
        assert!(!out.contains("Entering directory"), "{out}");
    }

    #[test]
    fn cmake_strips_checking_lines() {
        let raw = "-- Checking for module 'glib-2.0'\n-- Found glib-2.0\n-- Configuring done\n";
        let out = compress_cmake(raw);
        assert!(!out.contains("Checking for module"), "{out}");
        assert!(out.contains("Configuring done"));
    }
}
