from botocore.exceptions import ProfileNotFound

from awspipe.aws import SessionFactory
from awspipe.exceptions import AwspipeError


class RecordingSession:
    def __init__(self, profile_name=None, region_name=None) -> None:
        self.profile_name = profile_name
        self.region_name = region_name

    def client(self, service_name, region_name=None):
        assert service_name == "ec2"
        return RecordingEc2Client(region_name=region_name)


class RecordingEc2Client:
    def __init__(self, region_name=None) -> None:
        self.region_name = region_name

    def describe_regions(self, AllRegions=False):
        assert AllRegions is False
        return {"Regions": [{"RegionName": "eu-west-1"}, {"RegionName": "us-east-1"}]}


class MissingProfileSession:
    def __init__(self, profile_name=None, region_name=None) -> None:
        raise ProfileNotFound(profile='missing')


def test_session_factory_resolves_explicit_region(monkeypatch) -> None:
    monkeypatch.delenv("AWS_REGION", raising=False)
    factory = SessionFactory(session_cls=RecordingSession)
    session = factory.create(profile="dev", region="eu-west-1")

    assert factory.resolve_region(session, "eu-west-1") == "eu-west-1"


def test_session_factory_uses_environment_region(monkeypatch) -> None:
    monkeypatch.setenv("AWS_REGION", "us-east-2")
    factory = SessionFactory(session_cls=RecordingSession)
    session = factory.create(profile=None, region=None)

    assert factory.resolve_region(session, None) == "us-east-2"


def test_session_factory_resolves_all_regions() -> None:
    factory = SessionFactory(session_cls=RecordingSession)
    session = factory.create(profile="dev", region="eu-west-1")

    assert factory.resolve_regions(session, "eu-west-1", all_regions=True) == ["eu-west-1", "us-east-1"]


def test_session_factory_wraps_missing_profile() -> None:
    factory = SessionFactory(session_cls=MissingProfileSession)

    try:
        factory.create(profile="missing", region=None)
    except AwspipeError as exc:
        assert "AWS profile not found" in str(exc)
    else:
        raise AssertionError("Expected AwspipeError")
