"""Tests for firmware planning."""

from cnmaestro.devices import device_from_api
from cnmaestro.firmware import (
    FirmwareImage,
    _parse_version,
    chunked,
    latest_per_product,
    plan_upgrades,
)


def img(product, version, name=None):
    return FirmwareImage(
        product=product, version=version, name=name or version, raw={}
    )


def test_parse_version_orders():
    assert _parse_version("4.7.0") < _parse_version("4.7.1")
    assert _parse_version("4.7.0") < _parse_version("4.8.0")
    assert _parse_version("4.7.0") < _parse_version("5.0.0")


def test_latest_per_product():
    images = [
        img("ePMP", "4.7.0"),
        img("ePMP", "4.7.1"),
        img("ePMP", "4.6.2"),
        img("PMP", "20.3.1"),
        img("PMP", "20.3.2"),
    ]
    latest = latest_per_product(images)
    assert latest["ePMP"].version == "4.7.1"
    assert latest["PMP"].version == "20.3.2"


def test_plan_upgrades_skips_up_to_date_and_offline():
    devices = [
        device_from_api({"mac": "A1", "product": "ePMP", "status": "online",
                         "software_version": "4.7.0"}),
        device_from_api({"mac": "A2", "product": "ePMP", "status": "online",
                         "software_version": "4.7.1"}),  # already latest
        device_from_api({"mac": "A3", "product": "ePMP", "status": "offline",
                         "software_version": "4.7.0"}),  # offline, skip
        device_from_api({"mac": "B1", "product": "PMP", "status": "online",
                         "software_version": "20.3.0"}),
    ]
    images = [img("ePMP", "4.7.1"), img("PMP", "20.3.2")]
    groups = plan_upgrades(devices, images)
    macs_by_product = {g.product: {d.mac for d in g.devices} for g in groups}
    assert macs_by_product == {"ePMP": {"A1"}, "PMP": {"B1"}}


def test_plan_upgrades_product_filter():
    devices = [
        device_from_api({"mac": "A1", "product": "ePMP", "status": "online",
                         "software_version": "4.7.0"}),
        device_from_api({"mac": "B1", "product": "PMP", "status": "online",
                         "software_version": "20.3.0"}),
    ]
    images = [img("ePMP", "4.7.1"), img("PMP", "20.3.2")]
    groups = plan_upgrades(devices, images, products_filter={"ePMP"})
    assert len(groups) == 1
    assert groups[0].product == "ePMP"


def test_chunked():
    assert chunked([1, 2, 3, 4, 5], 2) == [[1, 2], [3, 4], [5]]
    assert chunked(list(range(250)), 100) == [
        list(range(0, 100)),
        list(range(100, 200)),
        list(range(200, 250)),
    ]
