"""Regression test: upload_dataset must raise on catalog registration failure.

Mirrors TypeScript SDK fix (05d3df3) — pseudo-success dicts replaced with exceptions.
"""

import pytest
from unittest.mock import MagicMock, patch, ANY

from helix_connect.exceptions import HelixError, ConflictError


def _make_producer():
    """Create a minimally-mocked HelixProducer (skip __init__)."""
    from helix_connect.producer import HelixProducer

    with patch.object(HelixProducer, "__init__", lambda self, **kw: None):
        p = HelixProducer.__new__(HelixProducer)
        return p


class TestUploadCatalogFailure:
    """upload_dataset must raise HelixError when catalog registration fails after S3 upload."""

    def test_raises_on_registration_failure(self, tmp_path):
        """POST /v1/datasets fails -> HelixError (clean failure, no upload)."""
        producer = _make_producer()
        # Create a real file so the early checks pass
        f = tmp_path / "data.ndjson"
        f.write_text('{"a":1}\n')

        producer.kms_key_id = None
        producer.customer_id = "cust-1"
        producer.bucket_name = "bucket"
        producer.s3 = MagicMock()

        # _analyze_data, _build_dataset_payload, _make_api_request are what matter
        with patch.object(producer, "_analyze_data", return_value=None), \
             patch.object(producer, "_build_dataset_payload", return_value={"_id": "ds-1", "name": "t"}), \
             patch.object(producer, "_make_api_request", side_effect=HelixError("500 Internal Server Error")):

            # Expect HelixError directly from _make_api_request
            with pytest.raises(HelixError, match="500 Internal Server Error"):
                producer.upload_dataset(
                    file_path=str(f),
                    dataset_name="test-ds",
                    encrypt=False,
                    compress=False,
                )

    def test_raises_on_conflict_update_failure(self, tmp_path):
        """POST returns 409, then PATCH update fails → HelixError."""
        producer = _make_producer()
        f = tmp_path / "data.ndjson"
        f.write_text('{"a":1}\n')

        producer.kms_key_id = None
        producer.customer_id = "cust-1"
        producer.bucket_name = "bucket"
        producer.s3 = MagicMock()

        # Mock requests.put to avoid actual connection attempts in case logic slips through
        with patch("helix_connect.producer.requests.put") as mock_put:
            with patch.object(producer, "_analyze_data", return_value=None), \
                 patch.object(producer, "_build_dataset_payload", return_value={"_id": "ds-1", "name": "t"}), \
                 patch.object(producer, "_make_api_request", side_effect=ConflictError("exists")), \
                 patch.object(producer, "_update_dataset_metadata", side_effect=HelixError("PATCH failed")):

                with pytest.raises(HelixError, match="PATCH failed"):
                    producer.upload_dataset(
                        file_path=str(f),
                        dataset_name="test-ds",
                        encrypt=False,
                        compress=False,
                    )
