import sys
import types
import unittest
from unittest import mock

from SystemUpdater.UpdatesAvailable import UpdateContentInfo


push_update_stub = types.ModuleType("SystemUpdater.push_update")
push_update_stub.UpdateContentInfo = UpdateContentInfo
sys.modules.setdefault("SystemUpdater.push_update", push_update_stub)

from SystemUpdater.backend.BackendOstreeNext import UpdateBackend


class TestPriorityUpgradeSelection(unittest.TestCase):
    def test_sort_push_content_orders_newest_timestamp_first_in_same_branch(self):
        backend = UpdateBackend.__new__(UpdateBackend)
        cur_deployed = UpdateContentInfo(
            repo_name="kylin",
            branch="kylin/desktop/v11/2603-update1/xc/general/all/build01/arm64",
        )
        older_push = UpdateContentInfo(
            repo_name="kylin",
            branch="kylin/desktop/v11/2603-update1/xc/general/all/build01/arm64",
            revision="77a7c20bbd419407fd785804abee1322cb0207adb266852d60c61f55889be27f",
            timestamp=1777278970,
            metadata={},
        )
        newer_push = UpdateContentInfo(
            repo_name="kylin",
            branch="kylin/desktop/v11/2603-update1/xc/general/all/build01/arm64",
            revision="723a3e75dc66d7738ed1ef0b07509548c5994e217ff0bef81db6dcd89ed5f4f6",
            timestamp=1777279326,
            metadata={},
        )

        sorted_push_content = backend._sort_push_content(
            [older_push, newer_push],
            cur_deployed,
        )

        self.assertEqual(newer_push.revision, sorted_push_content[0].revision)

    def test_sort_push_content_orders_newest_timestamp_first_in_other_branch_group(self):
        backend = UpdateBackend.__new__(UpdateBackend)
        cur_deployed = UpdateContentInfo(repo_name="kylin", branch="stable")
        older_other_branch = UpdateContentInfo(
            repo_name="kylin",
            branch="next",
            revision="other-older",
            timestamp=10,
            metadata={},
        )
        newer_other_branch = UpdateContentInfo(
            repo_name="kylin",
            branch="beta",
            revision="other-newer",
            timestamp=20,
            metadata={},
        )
        newest_same_branch = UpdateContentInfo(
            repo_name="kylin",
            branch="stable",
            revision="same-branch-newest",
            timestamp=999,
            metadata={},
        )

        sorted_push_content = backend._sort_push_content(
            [newest_same_branch, older_other_branch, newer_other_branch],
            cur_deployed,
        )

        self.assertEqual(newer_other_branch.revision, sorted_push_content[0].revision)

    def test_priority_upgrade_uses_first_sorted_push(self):
        backend = UpdateBackend.__new__(UpdateBackend)
        cur_deployed = UpdateContentInfo(repo_name="kylin", branch="stable")
        older_other_branch = UpdateContentInfo(
            repo_name="kylin",
            branch="next",
            revision="other-older",
            timestamp=10,
            metadata={},
        )
        newer_other_branch = UpdateContentInfo(
            repo_name="kylin",
            branch="beta",
            revision="other-newer",
            timestamp=20,
            metadata={},
        )
        newest_same_branch = UpdateContentInfo(
            repo_name="kylin",
            branch="stable",
            revision="same-branch-newest",
            timestamp=999,
            metadata={},
        )
        sorted_push_content = backend._sort_push_content(
            [newest_same_branch, older_other_branch, newer_other_branch],
            cur_deployed,
        )

        with mock.patch.object(backend, "_skip_deltas_selfupgrade", return_value=False), \
                mock.patch(
                    "SystemUpdater.backend.BackendOstreeNext.self_upgrade.run_priority_upgrade",
                    return_value=(False, []),
                ) as run_priority_upgrade:
            backend._handle_priority_upgrade(sorted_push_content, ostree_repo=mock.Mock())

        selected_push = run_priority_upgrade.call_args.args[1]
        self.assertEqual(newer_other_branch.revision, selected_push.revision)


if __name__ == "__main__":
    unittest.main()
