import pytest

from cpanel_mailgen.csvfile import CsvFileError, load, parse, render, render_cpanel_import

SEMI = "E-mail;Password\nalice@example.com;\nbob@example.com;\n"


def test_parses_semicolon_csv():
    data = parse(SEMI)
    assert data.emails == ["alice@example.com", "bob@example.com"]
    assert data.delimiter == ";"
    assert data.email_index == 0
    assert data.password_index == 1


def test_parses_comma_csv():
    data = parse("E-mail,Password\nalice@x.fr,\n")
    assert data.delimiter == ","


@pytest.mark.parametrize(
    "header",
    ["E-mail;Password", "email;password", "Adresse e-mail;Mot de passe", "Mail;MDP"],
)
def test_header_variants(header):
    data = parse(f"{header}\nalice@x.fr;\n")
    assert data.emails == ["alice@x.fr"]


def test_column_order_is_not_assumed():
    data = parse("Password;E-mail\n;alice@x.fr\n")
    assert data.email_index == 1
    assert data.password_index == 0
    assert data.emails == ["alice@x.fr"]


def test_extra_columns_are_preserved():
    data = parse("Nom;E-mail;Password;Quota\nAlice;alice@x.fr;;5G\n")
    out = render(data)
    assert "Alice" in out
    assert "5G" in out
    assert out.splitlines()[0] == "Nom;E-mail;Password;Quota"


def test_short_rows_are_padded_not_fatal():
    data = parse("E-mail;Password;Note\nalice@x.fr\n")
    assert data.rows[0] == ["alice@x.fr", "", ""]


def test_blank_lines_are_skipped():
    assert len(parse("E-mail;Password\nalice@x.fr;\n\n;\nbob@x.fr;\n").rows) == 2


def test_missing_email_column():
    with pytest.raises(CsvFileError, match="E-mail"):
        parse("Nom;Password\nAlice;x\n")


def test_missing_password_column():
    with pytest.raises(CsvFileError, match="Password"):
        parse("E-mail;Nom\nalice@x.fr;Alice\n")


def test_missing_email_value_is_reported():
    with pytest.raises(CsvFileError, match="ligne 2"):
        parse("E-mail;Password\n;secret\n")


def test_empty_csv():
    with pytest.raises(CsvFileError, match="vide"):
        parse("")


def test_header_only():
    with pytest.raises(CsvFileError, match="aucune ligne"):
        parse("E-mail;Password\n")


def test_bom_is_stripped(tmp_path):
    path = tmp_path / "c.csv"
    path.write_bytes(b"\xef\xbb\xbfE-mail;Password\r\nalice@x.fr;\r\n")
    assert load(path).emails == ["alice@x.fr"]


def test_render_keeps_the_original_delimiter():
    assert render(parse(SEMI)).splitlines()[0] == "E-mail;Password"
    assert render(parse("E-mail,Password\na@x.fr,\n")).splitlines()[0] == "E-mail,Password"


def test_render_round_trips():
    data = parse(SEMI)
    assert parse(render(data)).emails == data.emails


# --- import cPanel --------------------------------------------------------


def test_cpanel_import_has_three_columns_and_empty_quota():
    """Colonne Quota vide = quota illimite dans l'Address Importer."""
    data = parse("E-mail;Password\nalice@x.fr;motdepasse\n")
    lines = render_cpanel_import(data).strip().splitlines()
    assert lines == ["alice@x.fr,motdepasse,"]


def test_cpanel_import_is_comma_separated_whatever_the_input():
    data = parse("E-mail;Password\nalice@x.fr;pw\n")
    assert "," in render_cpanel_import(data)


def test_cpanel_import_with_explicit_quota():
    data = parse("E-mail;Password\nalice@x.fr;pw\n")
    assert render_cpanel_import(data, quota="4096").strip() == "alice@x.fr,pw,4096"


def test_cpanel_import_header_is_optional():
    data = parse("E-mail;Password\nalice@x.fr;pw\n")
    assert not render_cpanel_import(data).startswith("Email")
    assert render_cpanel_import(data, header=True).startswith("Email,Password,Quota")


def test_cpanel_import_ignores_extra_columns():
    data = parse("Nom;E-mail;Password;Note\nAlice;alice@x.fr;pw;bla\n")
    assert render_cpanel_import(data).strip() == "alice@x.fr,pw,"
