
import pytest


class FakeS3Client:
    def __init__(self):
        self.put_calls = []
        self.presign_calls = []

    def put_object(self, Bucket, Key, Body, ContentType=None):
        self.put_calls.append({
            'Bucket': Bucket,
            'Key': Key,
            'Body': Body,
            'ContentType': ContentType,
        })

    def generate_presigned_url(self, ClientMethod, Params, ExpiresIn):
        self.presign_calls.append({
            'ClientMethod': ClientMethod,
            'Params': Params,
            'ExpiresIn': ExpiresIn,
        })
        return f"https://example.com/{Params['Bucket']}/{Params['Key']}?e={ExpiresIn}"


@pytest.mark.asyncio
async def test_s3_backend_put_and_presign(monkeypatch):
    from src.fmatch.saas.storage.backends.s3_backend import S3Backend

    fake = FakeS3Client()

    def fake_client(service, region_name=None, endpoint_url=None, config=None):
        assert service == 's3'
        return fake

    monkeypatch.setenv('STORAGE_PROVIDER', 's3')
    monkeypatch.setenv('S3_BUCKET', 'my-bucket')
    monkeypatch.setenv('AWS_REGION', 'us-east-1')
    monkeypatch.setenv('SIGNED_URL_TTL_SEC', '123')
    monkeypatch.setenv('S3_ENDPOINT_URL', '')
    monkeypatch.setattr('src.fmatch.saas.storage.backends.s3_backend.boto3.client', fake_client)

    backend = S3Backend()

    class FakeUpload:
        filename = 'x.csv'
        content_type = 'text/csv'

        async def read(self):
            return b'abc,def\n1,2\n'

    url = await backend.save(FakeUpload(), 'k1/sample.csv')
    assert url == 's3://my-bucket/k1/sample.csv'
    assert fake.put_calls and fake.put_calls[0]['Bucket'] == 'my-bucket'
    assert fake.put_calls[0]['Key'] == 'k1/sample.csv'

    presigned = await backend.generate_presigned_url('k1/sample.csv', expires_in=None)
    assert presigned.startswith('https://example.com/my-bucket/k1/sample.csv')
    assert fake.presign_calls and fake.presign_calls[0]['ExpiresIn'] == 123


@pytest.mark.asyncio
async def test_tradeshow_service_uses_s3_backend(monkeypatch):
    # Ensure TradeshowService picks S3 when env says so
    monkeypatch.setenv('STORAGE_PROVIDER', 's3')
    monkeypatch.setenv('S3_BUCKET', 'bucket-x')
    from src.fmatch.saas.services.tradeshow_service import TradeshowService
    from src.fmatch.saas.storage.backends import s3_backend as s3b

    fake = FakeS3Client()

    def fake_client(service, region_name=None, endpoint_url=None, config=None):
        return fake

    monkeypatch.setattr('src.fmatch.saas.storage.backends.s3_backend.boto3.client', fake_client)

    # Fake db (only used for repo object creation in __init__)
    class DummyDB:
        pass

    svc = TradeshowService(db=DummyDB())
    # The storage object should be our S3Backend
    assert isinstance(svc.storage, s3b.S3Backend)

