import os
import tempfile

from iterable.datatypes.psv import PSVIterable, SSVIterable


def test_psv_read_write():
    """Test PSV (pipe-separated values) read and write"""
    test_data = [
        {"name": "Alice", "age": "30", "city": "New York"},
        {"name": "Bob", "age": "25", "city": "London"},
        {"name": "Charlie", "age": "35", "city": "Tokyo"},
    ]

    with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".psv", encoding="utf-8") as tmp:
        tmp_path = tmp.name
        # Write header
        tmp.write("name|age|city\n")
        # Write data
        for record in test_data:
            tmp.write(f"{record['name']}|{record['age']}|{record['city']}\n")

    try:
        # Read data
        reader = PSVIterable(tmp_path, mode="r")
        results = []
        for record in reader:
            results.append(record)
        reader.close()

        assert len(results) == 3
        assert results[0]["name"] == "Alice"
        assert results[0]["age"] == "30"

        # Write data
        with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".psv", encoding="utf-8") as tmp2:
            tmp2_path = tmp2.name

        writer = PSVIterable(tmp2_path, mode="w", keys=["name", "age", "city"])
        for record in test_data:
            writer.write(record)
        writer.close()

        # Verify written data
        with open(tmp2_path, encoding="utf-8") as f:
            lines = f.readlines()
            assert "name|age|city" in lines[0]
            assert "Alice|30|New York" in lines[1]

        if os.path.exists(tmp2_path):
            os.unlink(tmp2_path)
    finally:
        if os.path.exists(tmp_path):
            os.unlink(tmp_path)


def test_ssv_read_write():
    """Test SSV (semicolon-separated values) read and write"""
    test_data = [{"name": "Alice", "age": "30", "city": "New York"}, {"name": "Bob", "age": "25", "city": "London"}]

    with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".ssv", encoding="utf-8") as tmp:
        tmp_path = tmp.name
        # Write header
        tmp.write("name;age;city\n")
        # Write data
        for record in test_data:
            tmp.write(f"{record['name']};{record['age']};{record['city']}\n")

    try:
        # Read data
        reader = SSVIterable(tmp_path, mode="r")
        results = []
        for record in reader:
            results.append(record)
        reader.close()

        assert len(results) == 2
        assert results[0]["name"] == "Alice"

        # Write data
        with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".ssv", encoding="utf-8") as tmp2:
            tmp2_path = tmp2.name

        writer = SSVIterable(tmp2_path, mode="w", keys=["name", "age", "city"])
        for record in test_data:
            writer.write(record)
        writer.close()

        # Verify written data
        with open(tmp2_path, encoding="utf-8") as f:
            lines = f.readlines()
            assert "name;age;city" in lines[0]
            assert "Alice;30;New York" in lines[1]

        if os.path.exists(tmp2_path):
            os.unlink(tmp2_path)
    finally:
        if os.path.exists(tmp_path):
            os.unlink(tmp_path)


def test_psv_id():
    """Test PSV ID"""
    assert PSVIterable.id() == "psv"


def test_ssv_id():
    """Test SSV ID"""
    assert SSVIterable.id() == "ssv"


def test_psv_flatonly():
    """Test PSV is flat only"""
    assert PSVIterable.is_flatonly()


def test_ssv_flatonly():
    """Test SSV is flat only"""
    assert SSVIterable.is_flatonly()
