import lib


def test_taxonomiclookup_empty():
    lookup = lib.TaxonomicTree()
    assert lookup.size == 0


def test_taxonomiclookup_kingdom_size():
    lookup = lib.TaxonomicTree()

    lookup.add(("Animalia",))

    assert lookup.size == 1


def test_taxonomiclookup_genus_size():
    lookup = lib.TaxonomicTree()

    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Accipitriformes",
            "Accipitridae",
            "Halieaeetus",
        )
    )

    assert lookup.size == 6


def test_taxonomictree_kingdom_children():
    lookup = lib.TaxonomicTree()

    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Accipitriformes",
            "Accipitridae",
            "Halieaeetus",
        )
    )

    expected = set([("Animalia", 0)])
    actual = lookup.children()
    assert actual == expected


def test_taxonomiclookup_children_of_animal_only_birds():
    lookup = lib.TaxonomicTree()

    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Accipitriformes",
            "Accipitridae",
            "Halieaeetus",
            "leucocephalus",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "scutulata",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "plesseni",
        )
    )

    actual = lookup.children(("Animalia",))
    expected = set([("Chordata", 1)])
    assert actual == expected


def test_taxonomiclookup_children_of_animal():
    lookup = lib.TaxonomicTree()

    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Accipitriformes",
            "Accipitridae",
            "Halieaeetus",
            "leucocephalus",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "scutulata",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "plesseni",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Mammalia",
            "Primates",
            "Hominidae",
            "Gorilla",
            "gorilla",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Arthropoda",
            "Insecta",
            "Hymenoptera",
            "Apidae",
            "Bombus",
            "balteatus",
        )
    )

    actual = lookup.children(("Animalia",))
    expected = set([("Chordata", 1), ("Arthropoda", 17)])
    assert actual == expected


def test_taxonomiclookup_children_of_chordata():
    lookup = lib.TaxonomicTree()

    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Accipitriformes",
            "Accipitridae",
            "Halieaeetus",
            "leucocephalus",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "scutulata",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "plesseni",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Mammalia",
            "Primates",
            "Hominidae",
            "Gorilla",
            "gorilla",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Arthropoda",
            "Insecta",
            "Hymenoptera",
            "Apidae",
            "Bombus",
            "balteatus",
        )
    )

    actual = lookup.children(("Animalia", "Chordata"))
    expected = set([("Aves", 2), ("Mammalia", 12)])
    assert actual == expected


def test_taxonomiclookup_children_of_strigiformes():
    lookup = lib.TaxonomicTree()

    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Accipitriformes",
            "Accipitridae",
            "Halieaeetus",
            "leucocephalus",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "scutulata",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "plesseni",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Mammalia",
            "Primates",
            "Hominidae",
            "Gorilla",
            "gorilla",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Arthropoda",
            "Insecta",
            "Hymenoptera",
            "Apidae",
            "Bombus",
            "balteatus",
        )
    )

    actual = lookup.children(("Animalia", "Chordata", "Aves", "Strigiformes"))
    expected = set([("Strigidae", 8)])
    assert actual == expected


def test_taxonomiclookup_children_of_ninox():
    lookup = lib.TaxonomicTree()

    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Accipitriformes",
            "Accipitridae",
            "Halieaeetus",
            "leucocephalus",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "scutulata",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "plesseni",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Mammalia",
            "Primates",
            "Hominidae",
            "Gorilla",
            "gorilla",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Arthropoda",
            "Insecta",
            "Hymenoptera",
            "Apidae",
            "Bombus",
            "balteatus",
        )
    )

    actual = lookup.children(
        ("Animalia", "Chordata", "Aves", "Strigiformes", "Strigidae", "Ninox")
    )
    expected = set([("scutulata", 10), ("plesseni", 11)])
    assert actual == expected


def test_taxonomiclookup_children_of_gorilla():
    lookup = lib.TaxonomicTree()

    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Accipitriformes",
            "Accipitridae",
            "Halieaeetus",
            "leucocephalus",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "scutulata",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Aves",
            "Strigiformes",
            "Strigidae",
            "Ninox",
            "plesseni",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Chordata",
            "Mammalia",
            "Primates",
            "Hominidae",
            "Gorilla",
            "gorilla",
        )
    )
    lookup.add(
        (
            "Animalia",
            "Arthropoda",
            "Insecta",
            "Hymenoptera",
            "Apidae",
            "Bombus",
            "balteatus",
        )
    )

    actual = lookup.children(
        (
            "Animalia",
            "Chordata",
            "Mammalia",
            "Primates",
            "Hominidae",
            "Gorilla",
            "gorilla",
        )
    )
    expected = set()
    assert actual == expected


def test_taxonomictree_descendants_last():
    lookup = lib.TaxonomicTree()

    lookup.add(("A", "B", "C", "D", "E", "F", "G"))

    actual = list(lookup.descendants(("A", "B", "C", "D", "E", "F", "G")))

    expected = [
        (("A", "B", "C", "D", "E", "F", "G"), 6),
    ]
    assert actual == expected


def test_taxonomictree_descendants_entire_tree():
    lookup = lib.TaxonomicTree()

    lookup.add(("A", "B"))

    actual = list(lookup.descendants())

    expected = [
        (("A",), 0),
        (("A", "B"), 1),
    ]
    assert actual == expected


def test_taxonomictree_descendants_entire_tree_with_prefix():
    lookup = lib.TaxonomicTree()

    lookup.add(("A", "B"))

    actual = list(lookup.descendants(prefix=("A",)))

    expected = [
        (("A",), 0),
        (("A", "B"), 1),
    ]
    assert actual == expected


def test_taxonomictree_descendants_general():
    lookup = lib.TaxonomicTree()

    lookup.add(("A", "B", "C", "D", "E", "F", "G"))

    actual = list(lookup.descendants(("A", "B", "C", "D")))

    expected = [
        (("A", "B", "C", "D"), 3),
        (("A", "B", "C", "D", "E"), 4),
        (("A", "B", "C", "D", "E", "F"), 5),
        (("A", "B", "C", "D", "E", "F", "G"), 6),
    ]
    assert actual == expected