/// Filter out lines starting with "// Generated by Qleany" or "# Generated by Qleany"
/// so that version-stamp differences don't cause false "Modified" status or diffs.
pub(crate) fn strip_generated_by_lines(content: &str) -> String {
    content
        .lines()
        .filter(|line| {
            let trimmed = line.trim_start();
            !trimmed.starts_with("// Generated by Qleany")
                && !trimmed.starts_with("# Generated by Qleany")
        })
        .collect::<Vec<_>>()
        .join("\n")
}

/// Strip leading comment lines from a file (Rust `//` and C++ `//`, `/* */`, `#`).
/// Removes the contiguous block of comment/blank lines at the top of the file,
/// typically where a copyright header lives.
#[allow(dead_code)]
pub(crate) fn strip_comment_header(content: &str) -> String {
    let mut in_block_comment = false;
    let mut lines = content.lines().peekable();
    let mut skipped = true;

    // Skip leading comment and blank lines
    while skipped {
        skipped = false;
        while let Some(line) = lines.peek() {
            let trimmed = line.trim();

            if in_block_comment {
                skipped = true;
                if trimmed.contains("*/") {
                    in_block_comment = false;
                }
                lines.next();
                continue;
            }

            if trimmed.is_empty() {
                skipped = true;
                lines.next();
                continue;
            }

            if trimmed.starts_with("/*") {
                in_block_comment = true;
                skipped = true;
                if trimmed.contains("*/") {
                    in_block_comment = false;
                }
                lines.next();
                continue;
            }

            if trimmed.starts_with("//") || trimmed == "#" || trimmed.starts_with("# ") {
                skipped = true;
                lines.next();
                continue;
            }

            break;
        }
    }

    lines.collect::<Vec<_>>().join("\n")
}

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

    #[test]
    fn test_strip_generated_by_lines() {
        let input = "// Generated by Qleany v1.0\nuse foo;\nfn bar() {}";
        assert_eq!(strip_generated_by_lines(input), "use foo;\nfn bar() {}");
    }

    #[test]
    fn test_strip_generated_by_lines_hash() {
        let input = "# Generated by Qleany v1.0\n[package]\nname = \"foo\"";
        assert_eq!(strip_generated_by_lines(input), "[package]\nname = \"foo\"");
    }

    #[test]
    fn test_strip_comment_header_rust() {
        let input = "\
// Copyright 2024 Foo Inc.
// Licensed under MIT
// All rights reserved.

use std::io;

fn main() {}";
        assert_eq!(strip_comment_header(input), "use std::io;\n\nfn main() {}");
    }

    #[test]
    fn test_strip_comment_header_c_block() {
        let input = "\
/* Copyright 2024 Foo Inc.
 * Licensed under MIT
 * All rights reserved.
 */

#include <stdio.h>";
        assert_eq!(strip_comment_header(input), "#include <stdio.h>");
    }

    #[test]
    fn test_strip_comment_header_mixed() {
        let input = "\
// Line comment
/* Block comment */
// Another line

code_here();";
        assert_eq!(strip_comment_header(input), "code_here();");
    }

    #[test]
    fn test_strip_comment_header_no_header() {
        let input = "use foo;\nfn bar() {}";
        assert_eq!(strip_comment_header(input), "use foo;\nfn bar() {}");
    }

    #[test]
    fn test_strip_comment_header_hash_comments() {
        let input = "\
# Copyright header
# More comments

[package]
name = \"foo\"";
        assert_eq!(strip_comment_header(input), "[package]\nname = \"foo\"");
    }

    #[test]
    fn test_strip_comment_header_only_comments() {
        let input = "// just comments\n// nothing else";
        assert_eq!(strip_comment_header(input), "");
    }
}
