"""
Tests for error handling

Tests that proper error messages are raised for invalid inputs.
"""

import pytest
from smart_omop import (
    OMOPClient,
    CohortBuilderFull,
    MedSynthOMOPSource,
    Gender
)


BASE_URL = "http://ec2-13-49-5-87.eu-north-1.compute.amazonaws.com:8080/WebAPI"


def test_invalid_cohort_id():
    """Test error handling for invalid cohort ID."""
    with OMOPClient(BASE_URL) as client:
        with pytest.raises(ValueError, match="positive integer"):
            client.get_cohort(cohort_id=-1)

        with pytest.raises(ValueError, match="positive integer"):
            client.get_cohort(cohort_id=0)


def test_nonexistent_cohort():
    """Test error handling for non-existent cohort."""
    with OMOPClient(BASE_URL) as client:
        with pytest.raises(RuntimeError, match="does not exist"):
            client.get_cohort(cohort_id=999999)


def test_invalid_source_key():
    """Test error handling for invalid source key."""
    with OMOPClient(BASE_URL) as client:
        with pytest.raises(ValueError, match="non-empty string"):
            client.generate_cohort(cohort_id=145, source_key="")


def test_nonexistent_source():
    """Test error handling for non-existent source."""
    with OMOPClient(BASE_URL) as client:
        with pytest.raises(RuntimeError, match="not found"):
            client.get_generation_status(cohort_id=145, source_key="NONEXISTENT")


def test_cohort_not_generated():
    """Test error handling for cohort not yet generated."""
    with OMOPClient(BASE_URL) as client:
        with pytest.raises(RuntimeError, match="has not been generated"):
            client.get_cohort_results(cohort_id=999, source_key="KAGGLECOPD")


def test_invalid_cohort_definition():
    """Test error handling for invalid cohort definition."""
    with OMOPClient(BASE_URL) as client:
        with pytest.raises(ValueError, match="must be a dictionary"):
            client.create_cohort("not a dict")

        with pytest.raises(ValueError, match="'name' field"):
            client.create_cohort({})

        with pytest.raises(ValueError, match="'expression' field"):
            client.create_cohort({"name": "Test"})


def test_empty_concept_set():
    """Test error handling for empty concept set."""
    builder = CohortBuilderFull("Test", "Test")
    cs = builder.add_concept_set("Empty")
    builder.add_primary_condition(0)

    with pytest.raises(RuntimeError, match="empty"):
        builder.build()


def test_no_primary_criteria():
    """Test error handling for missing primary criteria."""
    builder = CohortBuilderFull("Test", "Test")
    cs = builder.add_concept_set("Test")
    cs.add_concept(255573)

    with pytest.raises(RuntimeError, match="primary criterion"):
        builder.build()


def test_invalid_concept_id():
    """Test error handling for invalid concept ID."""
    builder = CohortBuilderFull("Test", "Test")
    cs = builder.add_concept_set("Test")

    with pytest.raises(ValueError, match="positive integer"):
        cs.add_concept(-1)

    with pytest.raises(ValueError, match="positive integer"):
        cs.add_concept(0)


def test_medsynth_invalid_directory():
    """Test error handling for invalid MedSynth directory."""
    with pytest.raises(ValueError, match="not found"):
        MedSynthOMOPSource("/nonexistent/path")

    with pytest.raises(ValueError, match="required"):
        MedSynthOMOPSource("")


def test_medsynth_invalid_table():
    """Test error handling for invalid table name."""
    import tempfile
    import os

    with tempfile.TemporaryDirectory() as tmpdir:
        source = MedSynthOMOPSource(tmpdir)

        with pytest.raises(ValueError, match="Unknown table"):
            source.load_table("invalid_table")

        with pytest.raises(ValueError, match="required"):
            source.load_table("")


def test_medsynth_missing_table_file():
    """Test error handling for missing table file."""
    import tempfile

    with tempfile.TemporaryDirectory() as tmpdir:
        source = MedSynthOMOPSource(tmpdir)

        with pytest.raises(RuntimeError, match="not found"):
            source.load_table("person")
