#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tests for rust_watch.py."""

import logging
import pathlib
import subprocess
import time
import unittest
import unittest.mock

from cros_utils import tiny_render
import rust_watch


class Test(unittest.TestCase):
    """Tests."""

    def _silence_logs(self):
        """Silences all log output until the end of the current test."""

        def should_log(_record):
            return 0

        logger = logging.root
        logger.addFilter(should_log)
        self.addCleanup(logger.removeFilter, should_log)

    def test_release_version_parsing(self):
        self.assertEqual(
            rust_watch.RustReleaseVersion.from_string("1.2.3"),
            rust_watch.RustReleaseVersion(1, 2, 3),
        )

    def test_release_version_json_round_trips(self):
        ver = rust_watch.RustReleaseVersion(1, 2, 3)
        self.assertEqual(
            rust_watch.RustReleaseVersion.from_json(ver.to_json()), ver
        )

    def test_state_json_round_trips(self):
        state = rust_watch.State(
            last_seen_release=rust_watch.RustReleaseVersion(1, 2, 3),
            last_gentoo_sha="abc123",
        )

        self.assertEqual(rust_watch.State.from_json(state.to_json()), state)

    @unittest.mock.patch.object(subprocess, "run")
    @unittest.mock.patch.object(time, "sleep")
    def test_update_git_repo_tries_again_on_failure(self, sleep_mock, run_mock):
        self._silence_logs()

        oh_no_error = ValueError("oh no")

        def check_returncode():
            raise oh_no_error

        run_call_count = 0

        def run_sideeffect(*_args, **_kwargs):
            nonlocal run_call_count
            run_call_count += 1
            result = unittest.mock.Mock()
            result.returncode = 1
            result.check_returncode = check_returncode
            return result

        run_mock.side_effect = run_sideeffect

        with self.assertRaises(ValueError) as raised:
            rust_watch.update_git_repo(pathlib.Path("/does/not/exist/at/all"))

        self.assertIs(raised.exception, oh_no_error)
        self.assertEqual(run_call_count, 5)

        sleep_timings = [unittest.mock.call(60 * i) for i in range(1, 5)]
        self.assertEqual(sleep_mock.mock_calls, sleep_timings)

    @unittest.mock.patch.object(subprocess, "run")
    def test_get_new_gentoo_commits_functions(self, run_mock):
        returned = unittest.mock.Mock()
        returned.returncode = 0
        returned.stdout = "\n".join(
            (
                "abc123 newer commit",
                "abcdef and an older commit",
            )
        )
        run_mock.return_value = returned
        results = rust_watch.get_new_gentoo_commits(
            pathlib.Path("/does/not/exist/at/all"), "defabc"
        )
        self.assertEqual(
            results,
            [
                rust_watch.GitCommit("abcdef", "and an older commit"),
                rust_watch.GitCommit("abc123", "newer commit"),
            ],
        )

    def test_compose_email_on_a_new_gentoo_commit(self):
        sha_a = "a" * 40
        new_commit = rust_watch.maybe_compose_email(
            new_gentoo_commits=[
                rust_watch.GitCommit(
                    sha=sha_a,
                    subject="summary_a",
                ),
            ],
        )

        self.assertEqual(
            new_commit,
            (
                "[rust-watch] new rust ebuild commit detected",
                [
                    "commit:",
                    tiny_render.UnorderedList(
                        [
                            [
                                tiny_render.Link(
                                    rust_watch.gentoo_sha_to_link(sha_a),
                                    sha_a[:12],
                                ),
                                ": summary_a",
                            ],
                        ]
                    ),
                ],
            ),
        )

    def test_compose_email_composes_nothing_when_no_new_updates_exist(self):
        self.assertIsNone(rust_watch.maybe_compose_email(new_gentoo_commits=()))

    def test_compose_bug_creates_bugs_on_new_versions(self):
        title, body = rust_watch.maybe_compose_bug(
            old_state=rust_watch.State(
                last_seen_release=rust_watch.RustReleaseVersion(1, 0, 0),
                last_gentoo_sha="",
            ),
            newest_release=rust_watch.RustReleaseVersion(1, 0, 1),
        )
        self.assertEqual(title, "[Rust] Update to 1.0.1")
        self.assertTrue(body.startswith("A new release has been detected;"))

        title, body = rust_watch.maybe_compose_bug(
            old_state=rust_watch.State(
                last_seen_release=rust_watch.RustReleaseVersion(1, 0, 0),
                last_gentoo_sha="",
            ),
            newest_release=rust_watch.RustReleaseVersion(1, 1, 0),
        )
        self.assertEqual(title, "[Rust] Update to 1.1.0")
        self.assertTrue(body.startswith("A new release has been detected;"))

        title, body = rust_watch.maybe_compose_bug(
            old_state=rust_watch.State(
                last_seen_release=rust_watch.RustReleaseVersion(1, 0, 0),
                last_gentoo_sha="",
            ),
            newest_release=rust_watch.RustReleaseVersion(2, 0, 0),
        )
        self.assertEqual(title, "[Rust] Update to 2.0.0")
        self.assertTrue(body.startswith("A new release has been detected;"))

    def test_compose_bug_does_nothing_when_no_new_updates_exist(self):
        self.assertIsNone(
            rust_watch.maybe_compose_bug(
                old_state=rust_watch.State(
                    last_seen_release=rust_watch.RustReleaseVersion(1, 0, 0),
                    last_gentoo_sha="",
                ),
                newest_release=rust_watch.RustReleaseVersion(1, 0, 0),
            )
        )


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