# Copyright © The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.

"""Unit tests for scheduler tags backend functions."""

from unittest import TestCase

from debusine.server.tags import Tagset
from debusine.utils.tag_utils import DerivationRules, ProvenanceRestrictions


class TagsetTests(TestCase):
    """Tests for :py:class:`Tagset`."""

    def test_init(self) -> None:
        t = Tagset()
        self.assertEqual(t.restrictions, [])
        self.assertEqual(t.derivation_rules, [])
        self.assertEqual(t.tags, set())
        self.assertEqual(t.log, [])

    def test_plain(self) -> None:
        t = Tagset()
        t.add("test", None)
        t.add("test", ["foo"])
        t.add("test", {"bar", "baz"})
        t.finalize()
        self.assertEqual(t.tags, {"foo", "bar", "baz"})

    def test_restrictions(self) -> None:
        restrictions = ProvenanceRestrictions("test")
        restrictions.add_exact("group", ["system"])
        restrictions.add_exact("test", ["system"])
        t = Tagset()
        t.restrictions.append(restrictions)
        t.add("system", {"test", "foo"})
        t.add("workspace", {"group", "bar"})
        t.finalize()
        self.assertEqual(t.tags, {"test", "foo", "bar"})
        self.assertEqual(
            t.log, ["test provenance restrictions forbids tags group"]
        )

    def test_derivation(self) -> None:
        derivation = DerivationRules(provenance="system")
        derivation.add_rule("dm or dd", {"debian"})
        t = Tagset()
        t.derivation_rules.append(derivation)
        t.add("system", {"dm", "foo"})
        t.finalize()
        self.assertEqual(t.tags, {"dm", "debian", "foo"})
        self.assertEqual(t.log, ["system derivation rules adds tags debian"])

    def test_derivation_exists_but_does_not_match(self) -> None:
        derivation = DerivationRules(provenance="system")
        derivation.add_rule("dm or dd", {"debian"})
        t = Tagset()
        t.derivation_rules.append(derivation)
        t.add("system", {"foo"})
        t.finalize()
        self.assertEqual(t.tags, {"foo"})
        self.assertEqual(t.log, [])

    def test_derivation_restrictions(self) -> None:
        restrictions = ProvenanceRestrictions("test")
        restrictions.add_exact("group", ["system"])
        derivation = DerivationRules(provenance="workspace")
        derivation.add_rule("dm or dd", {"debian"})
        derivation.add_rule("foo", {"group"})
        t = Tagset()
        t.restrictions.append(restrictions)
        t.derivation_rules.append(derivation)
        t.add("system", {"test", "foo", "dm"})
        t.finalize()
        self.assertEqual(t.tags, {"test", "foo", "dm", "debian"})
        self.assertEqual(
            t.log,
            [
                "workspace derivation rules adds tags debian, group",
                "test provenance restrictions forbids tags group",
            ],
        )
