"""Tests for V3 Files API (multipart upload)."""

from pytest_httpx import HTTPXMock

from concentriq import ConcentriqClient
from concentriq.auth import ApiKeyAuth


class TestFilesCreateMultipartUpload:
    """Tests for Files.create_multipart_upload() behavior."""

    def test_create_multipart_upload_returns_upload_metadata(self, httpx_mock: HTTPXMock):
        """Should return Bucket, Key, and UploadId from S3."""
        httpx_mock.add_response(
            method="POST",
            json={
                "Bucket": "my-bucket",
                "Key": "1/users/1/images/100/slide.tif",
                "UploadId": "abc123",
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v3.files.create_multipart_upload(
            resource_type="Image", resource_id=100, storage_key="1/users/1/images/100/slide.tif"
        )

        assert result["UploadId"] == "abc123"
        assert result["Bucket"] == "my-bucket"

        request = httpx_mock.get_request()
        assert request.url.params["resourceType"] == "Image"
        assert request.url.params["resourceId"] == "100"
        assert request.url.params["storageKey"] == "1/users/1/images/100/slide.tif"


class TestFilesGetPartUploadUrl:
    """Tests for Files.get_part_upload_url() behavior."""

    def test_get_part_upload_url_returns_presigned_url(self, httpx_mock: HTTPXMock):
        """Should return a presigned S3 URL for the part."""
        httpx_mock.add_response(
            json={"url": "https://s3.amazonaws.com/bucket/key?signed=true"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        url = client.v3.files.get_part_upload_url(
            resource_type="Image",
            resource_id=100,
            storage_key="1/users/1/images/100/slide.tif",
            upload_id="abc123",
            part_number=1,
        )

        assert url == "https://s3.amazonaws.com/bucket/key?signed=true"

        request = httpx_mock.get_request()
        assert request.url.params["PartNumber"] == "1"
        assert request.url.params["UploadId"] == "abc123"


class TestFilesCompleteMultipartUpload:
    """Tests for Files.complete_multipart_upload() behavior."""

    def test_complete_multipart_upload_sends_parts(self, httpx_mock: HTTPXMock):
        """Should POST parts list to complete the upload."""
        httpx_mock.add_response(method="POST", status_code=200)

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        parts = [
            {"PartNumber": 1, "ETag": '"etag1"'},
            {"PartNumber": 2, "ETag": '"etag2"'},
        ]
        client.v3.files.complete_multipart_upload(
            resource_type="Image",
            resource_id=100,
            storage_key="1/users/1/images/100/slide.tif",
            upload_id="abc123",
            parts=parts,
        )

        request = httpx_mock.get_request()
        assert request.url.params["UploadId"] == "abc123"
        import json
        body = json.loads(request.content)
        assert len(body["Parts"]) == 2
        assert body["Parts"][0]["ETag"] == '"etag1"'


class TestFilesAbortMultipartUpload:
    """Tests for Files.abort_multipart_upload() behavior."""

    def test_abort_multipart_upload_succeeds(self, httpx_mock: HTTPXMock):
        """Should POST to abort the upload."""
        httpx_mock.add_response(method="POST", status_code=200)

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        client.v3.files.abort_multipart_upload(
            resource_type="Image",
            resource_id=100,
            storage_key="1/users/1/images/100/slide.tif",
            upload_id="abc123",
        )

        request = httpx_mock.get_request()
        assert request.url.params["UploadId"] == "abc123"


class TestFilesGetUploadUrl:
    """Tests for Files.get_upload_url() (single-part) behavior."""

    def test_get_upload_url_returns_presigned_url(self, httpx_mock: HTTPXMock):
        """Should return a presigned S3 URL for single-part upload."""
        httpx_mock.add_response(
            json={"url": "https://s3.amazonaws.com/bucket/key?signed=true"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        url = client.v3.files.get_upload_url(
            resource_type="Image",
            resource_id=100,
            storage_key="1/users/1/images/100/slide.tif",
        )

        assert url == "https://s3.amazonaws.com/bucket/key?signed=true"
