# Copyright {{ year }} {{ author }}
# See LICENSE file for licensing details.
#
# To learn more about testing, see https://documentation.ubuntu.com/ops/latest/explanation/testing/

import pytest
from ops import pebble, testing

from charm import SERVICE_NAME, {{ class_name }}

CHECK_NAME = "service-ready"  # Name of Pebble check in the mock workload container.

layer = pebble.Layer(
    {
        "services": {
            SERVICE_NAME: {
                "override": "replace",
                "command": "/bin/foo",  # The specific command isn't important for unit tests.
                "startup": "enabled",
            }
        },
        "checks": {
            CHECK_NAME: {
                "override": "replace",
                "level": "ready",
                "threshold": 3,
                "startup": "enabled",
                "http": {
                    "url": "http://localhost:8000/version",  # The specific URL isn't important.
                },
            }
        },
    }
)


def mock_get_version():
    """Get a mock version string without executing the workload code."""
    return "1.0.0"


def test_pebble_ready(monkeypatch: pytest.MonkeyPatch):
    """Test that the charm has the correct state after handling the pebble-ready event."""
    # Arrange:
    ctx = testing.Context({{ class_name }})
    check_in = testing.CheckInfo(
        CHECK_NAME,
        level=pebble.CheckLevel.READY,
        status=pebble.CheckStatus.UP,  # Simulate the Pebble check passing.
    )
    container_in = testing.Container(
        "some-container",
        can_connect=True,
        layers={"base": layer},
        service_statuses={SERVICE_NAME: pebble.ServiceStatus.INACTIVE},
        check_infos={check_in},
    )
    state_in = testing.State(containers={container_in})
    monkeypatch.setattr("charm.{{ workload_module }}.get_version", mock_get_version)

    # Act:
    state_out = ctx.run(ctx.on.pebble_ready(container_in), state_in)

    # Assert:
    container_out = state_out.get_container(container_in.name)
    assert container_out.service_statuses[SERVICE_NAME] == pebble.ServiceStatus.ACTIVE
    assert state_out.workload_version is not None
    assert state_out.unit_status == testing.ActiveStatus()


def test_pebble_ready_service_not_ready():
    """Test that the charm raises an error if the workload isn't ready after Pebble starts it."""
    # Arrange:
    ctx = testing.Context({{ class_name }})
    check_in = testing.CheckInfo(
        CHECK_NAME,
        level=pebble.CheckLevel.READY,
        status=pebble.CheckStatus.DOWN,  # Simulate the Pebble check failing.
    )
    container_in = testing.Container(
        "some-container",
        can_connect=True,
        layers={"base": layer},
        service_statuses={SERVICE_NAME: pebble.ServiceStatus.INACTIVE},
        check_infos={check_in},
    )
    state_in = testing.State(containers={container_in})

    # Act & assert:
    with pytest.raises(testing.errors.UncaughtCharmError):
        ctx.run(ctx.on.pebble_ready(container_in), state_in)
