//! Section 7.3 — Edge cases.

use crate::{parse, Entry, ParseError, 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.3 Case 1 — empty input yields no entries and no errors.
#[test]
fn empty_input() {
    let entries = parse(b"").unwrap();
    assert!(entries.is_empty());
}

/// 7.3 Case 2 — `#=foo` and `#key=value` are comment lines, not data lines.
#[test]
fn comments_not_data() {
    let input = b"#=foo\n#key=value\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![
        comment(1, "=foo"),
        comment(2, "key=value"),
    ]);
}

/// 7.3 Case 3 — `key==foo` → value is `=foo`.
#[test]
fn double_equals() {
    let input = b"key==foo\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![kv(1, "key", "=foo")]);
}

/// 7.3 Case 4 — `key=` → empty string value.
#[test]
fn empty_value_edge() {
    let input = b"key=\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![kv(1, "key", "")]);
}

/// 7.3 Case 5 — `key = abc` → value is ` abc` (leading space preserved).
///
/// After stripping leading line whitespace the line is `key = abc`.
/// The key is `key` (trailing whitespace before `=` stripped),
/// the value is ` abc` (everything after `=`, verbatim).
#[test]
fn leading_space_in_value() {
    let input = b"key = abc\n";
    let entries = parse(input).unwrap();
    assert_eq!(entries, vec![kv(1, "key", " abc")]);
}

/// 7.3 Case 6 — space is not an operator (`MISSING_OPERATOR_ERROR`).
#[test]
fn space_not_operator() {
    let errors = parse(b"key value\n").unwrap_err();
    assert_eq!(errors, vec![ParseError::MissingOperatorError { line: 1 }]);
}

/// 7.3 Case 7 — colon is not an operator (`MISSING_OPERATOR_ERROR`).
#[test]
fn colon_not_operator() {
    let errors = parse(b"key:value\n").unwrap_err();
    assert_eq!(errors, vec![ParseError::MissingOperatorError { line: 1 }]);
}

/// 7.3 Case 8 — `key:=value` → colon in key → `INVALID_KEY_ERROR`.
#[test]
fn colon_in_key() {
    let errors = parse(b"key:=value\n").unwrap_err();
    assert_eq!(errors, vec![ParseError::InvalidKeyError { line: 1 }]);
}

/// 7.3 Case 9 — `foo bar=value` → space in key → `INVALID_KEY_ERROR`.
#[test]
fn space_in_key() {
    let errors = parse(b"foo bar=value\n").unwrap_err();
    assert_eq!(errors, vec![ParseError::InvalidKeyError { line: 1 }]);
}

/// Blank lines are suppressed by default but can be enabled via config.
#[test]
fn blank_lines_with_config() {
    let config = ParserConfig { emit_blanks: true, emit_comments: false, ..ParserConfig::default() };
    let input = b"KEY=value\n\n";
    let entries = parse_with_config(input, &config).unwrap();
    assert_eq!(entries, vec![
        kv(1, "KEY", "value"),
        Entry::Blank { line: 2 },
    ]);
}
