//! Section 7.1 — Valid examples.

use crate::{parse, Entry, ParserConfig, parse_with_config};

fn kv(line: u32, key: &str, value: &str) -> Entry {
    Entry::Kv { line, key: key.to_owned(), value: value.to_owned() }
}

fn comment(line: u32, text: &str) -> Entry {
    Entry::Comment { line, text: text.to_owned() }
}

/// 7.1 Example 1 — simple key-value pairs.
#[test]
fn simple_kv() {
    let input = b"APP_NAME=My Application\nAPI_KEY=sk_live_1234567890abcdef\nDEBUG=true\nPATH=/usr/local/bin:/usr/bin\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![
        kv(1, "APP_NAME", "My Application"),
        kv(2, "API_KEY", "sk_live_1234567890abcdef"),
        kv(3, "DEBUG", "true"),
        kv(4, "PATH", "/usr/local/bin:/usr/bin"),
    ]);
}

/// 7.1 Example 2 — empty value.
#[test]
fn empty_value() {
    let input = b"EMPTY=\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![kv(1, "EMPTY", "")]);
}

/// 7.1 Example 3 — leading and trailing space in values preserved.
#[test]
fn value_whitespace_preserved() {
    let input = b"trailing=foo \nleading= bar\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![
        kv(1, "trailing", "foo "),
        kv(2, "leading", " bar"),
    ]);
}

/// 7.1 Example 4 — no inline comments (hash in value is literal).
#[test]
fn no_inline_comments() {
    let input = b"NOT_AS_INTENDED=1 # default value\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![kv(1, "NOT_AS_INTENDED", "1 # default value")]);
}

/// 7.1 Example 5 — quotes are literal characters.
#[test]
fn quotes_literal() {
    let input = b"quoted=\"hello\"\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![kv(1, "quoted", "\"hello\"")]);
}

/// 7.1 Example 6 — backslashes are never used as escapes.
#[test]
fn backslash_literal() {
    let input = b"BACKSLASH=\\n\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![kv(1, "BACKSLASH", "\\n")]);
}

/// 7.1 Example 7 — no interpolation (dollar sign is literal).
#[test]
fn no_interpolation() {
    let input = b"PATH=/usr/bin\nPATH=$PATH:/usr/var/bin\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![
        kv(1, "PATH", "/usr/bin"),
        kv(2, "PATH", "$PATH:/usr/var/bin"),
    ]);
}

/// 7.1 Example 8 — empty comment.
#[test]
fn empty_comment() {
    let input = b"#\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![comment(1, "")]);
}

/// 7.1 Example 9 — comment consisting of a single space.
#[test]
fn comment_space() {
    let input = b"# \n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![comment(1, " ")]);
}

/// 7.1 Example 10 — comment with leading and trailing spaces.
#[test]
fn comment_with_spaces() {
    let input = b"#  comment   \n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![comment(1, "  comment   ")]);
}

/// 7.1 Example 11 — duplicate keys are valid.
#[test]
fn duplicate_keys() {
    let input = b"KEY=1\nKEY=2\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![
        kv(1, "KEY", "1"),
        kv(2, "KEY", "2"),
    ]);
}

/// Verify that comments are suppressed when `emit_comments` is false.
#[test]
fn comments_suppressed() {
    let config = ParserConfig { emit_comments: false, ..ParserConfig::default() };
    let input = b"# comment\nKEY=val\n";
    let entries = parse_with_config(input, &config).unwrap();
    assert_eq!(entries, vec![kv(2, "KEY", "val")]);
}
