"""Test docker login."""

import pytest

# pylint: disable=protected-access
from supervisor.coresys import CoreSys
from supervisor.docker.const import DOCKER_HUB, DOCKER_HUB_LEGACY
from supervisor.docker.interface import DockerInterface
from supervisor.docker.utils import get_registry_from_image


@pytest.mark.parametrize(
    ("image_ref", "expected_registry"),
    [
        # No registry - Docker Hub images
        ("nginx", None),
        ("nginx:latest", None),
        ("library/nginx", None),
        ("library/nginx:latest", None),
        ("homeassistant/amd64-supervisor", None),
        ("homeassistant/amd64-supervisor:1.2.3", None),
        # Registry with dot
        ("ghcr.io/homeassistant/amd64-supervisor", "ghcr.io"),
        ("ghcr.io/homeassistant/amd64-supervisor:latest", "ghcr.io"),
        ("myregistry.com/nginx", "myregistry.com"),
        ("registry.example.com/org/image:v1", "registry.example.com"),
        ("127.0.0.1/myimage", "127.0.0.1"),
        # Registry with port
        ("myregistry:5000/myimage", "myregistry:5000"),
        ("localhost:5000/myimage", "localhost:5000"),
        ("registry.io:5000/org/app:v1", "registry.io:5000"),
        # localhost special case
        ("localhost/myimage", "localhost"),
        ("localhost/myimage:tag", "localhost"),
        # IPv6
        ("[::1]:5000/myimage", "[::1]:5000"),
        ("[2001:db8::1]:5000/myimage:tag", "[2001:db8::1]:5000"),
    ],
)
def test_get_registry_from_image(image_ref: str, expected_registry: str | None):
    """Test get_registry_from_image extracts registry from image reference.

    Based on Docker's reference implementation:
    vendor/github.com/distribution/reference/normalize.go
    """
    assert get_registry_from_image(image_ref) == expected_registry


def test_no_credentials(coresys: CoreSys, test_docker_interface: DockerInterface):
    """Test no credentials."""
    coresys.docker.config._data["registries"] = {
        DOCKER_HUB: {"username": "Spongebob Squarepants", "password": "Password1!"}
    }
    credentials, image = test_docker_interface._get_credentials("ghcr.io/homeassistant")
    assert not credentials
    assert image == "ghcr.io/homeassistant"

    credentials, image = test_docker_interface._get_credentials(
        "ghcr.io/homeassistant/amd64-supervisor"
    )
    assert not credentials
    assert image == "ghcr.io/homeassistant/amd64-supervisor"


def test_no_matching_credentials(
    coresys: CoreSys, test_docker_interface: DockerInterface
):
    """Test no matching credentials."""
    coresys.docker.config._data["registries"] = {
        DOCKER_HUB: {"username": "Spongebob Squarepants", "password": "Password1!"}
    }
    credentials, image = test_docker_interface._get_credentials("ghcr.io/homeassistant")
    assert not credentials
    assert image == "ghcr.io/homeassistant"

    credentials, image = test_docker_interface._get_credentials(
        "ghcr.io/homeassistant/amd64-supervisor"
    )
    assert not credentials
    assert image == "ghcr.io/homeassistant/amd64-supervisor"


def test_matching_credentials(coresys: CoreSys, test_docker_interface: DockerInterface):
    """Test matching credentials."""
    coresys.docker.config._data["registries"] = {
        "ghcr.io": {"username": "Octocat", "password": "Password1!"},
        DOCKER_HUB: {"username": "Spongebob Squarepants", "password": "Password1!"},
    }

    credentials, image = test_docker_interface._get_credentials(
        "ghcr.io/homeassistant/amd64-supervisor"
    )
    assert credentials["registry"] == "ghcr.io"
    assert image == "ghcr.io/homeassistant/amd64-supervisor"

    credentials, image = test_docker_interface._get_credentials(
        "homeassistant/amd64-supervisor"
    )
    assert credentials["username"] == "Spongebob Squarepants"
    assert credentials["registry"] == DOCKER_HUB
    # Docker Hub images should be prefixed with docker.io/ for correct ServerAddress
    assert image == f"{DOCKER_HUB}/homeassistant/amd64-supervisor"


def test_legacy_docker_hub_credentials(
    coresys: CoreSys, test_docker_interface: DockerInterface
):
    """Test legacy hub.docker.com credentials are used for Docker Hub images."""
    coresys.docker.config._data["registries"] = {
        DOCKER_HUB_LEGACY: {"username": "LegacyUser", "password": "Password1!"},
    }

    credentials, image = test_docker_interface._get_credentials(
        "homeassistant/amd64-supervisor"
    )
    assert credentials["username"] == "LegacyUser"
    assert credentials["registry"] == DOCKER_HUB_LEGACY
    assert image == f"{DOCKER_HUB}/homeassistant/amd64-supervisor"


def test_docker_hub_preferred_over_legacy(
    coresys: CoreSys, test_docker_interface: DockerInterface
):
    """Test docker.io is preferred over legacy hub.docker.com when both exist."""
    coresys.docker.config._data["registries"] = {
        DOCKER_HUB: {"username": "NewUser", "password": "Password1!"},
        DOCKER_HUB_LEGACY: {"username": "LegacyUser", "password": "Password2!"},
    }

    credentials, image = test_docker_interface._get_credentials(
        "homeassistant/amd64-supervisor"
    )
    # docker.io should be preferred
    assert credentials["username"] == "NewUser"
    assert credentials["registry"] == DOCKER_HUB
    assert image == f"{DOCKER_HUB}/homeassistant/amd64-supervisor"
