# Copyright 2014 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Test the archive_lib module."""

from unittest import mock

from chromite.cbuildbot import archive_lib
from chromite.cbuildbot import cbuildbot_run
from chromite.lib import config_lib
from chromite.lib import config_lib_unittest
from chromite.lib import cros_test_lib
from chromite.lib import parallel_unittest
from chromite.utils import gs_urls_util


DEFAULT_ARCHIVE_PREFIX = "bogus_bucket/TheArchiveBase"
DEFAULT_ARCHIVE_BASE = "gs://%s" % DEFAULT_ARCHIVE_PREFIX
DEFAULT_BUILDROOT = "/tmp/foo/bar/buildroot"
DEFAULT_BUILDNUMBER = 12345
DEFAULT_BRANCH = "TheBranch"
DEFAULT_CHROME_BRANCH = "TheChromeBranch"
DEFAULT_VERSION_STRING = "TheVersionString"
DEFAULT_BOARD = "TheBoard"
DEFAULT_BOT_NAME = "TheCoolBot"

# Access to protected member.
# pylint: disable=protected-access

DEFAULT_OPTIONS = cros_test_lib.EasyAttr(
    archive_base=DEFAULT_ARCHIVE_BASE,
    buildroot=DEFAULT_BUILDROOT,
    buildnumber=DEFAULT_BUILDNUMBER,
    buildbot=True,
    branch=DEFAULT_BRANCH,
    remote_trybot=False,
    debug=False,
)
DEFAULT_CONFIG = config_lib.BuildConfig(
    name=DEFAULT_BOT_NAME,
    master=True,
    boards=[DEFAULT_BOARD],
    gs_path=config_lib.GS_PATH_DEFAULT,
)


def _ExtendDefaultOptions(**kwargs):
    """Extend DEFAULT_OPTIONS with keys/values in kwargs."""
    options_kwargs = DEFAULT_OPTIONS.copy()
    options_kwargs.update(kwargs)
    return cros_test_lib.EasyAttr(**options_kwargs)


def _ExtendDefaultConfig(**kwargs):
    """Extend DEFAULT_CONFIG with keys/values in kwargs."""
    config_kwargs = DEFAULT_CONFIG.copy()
    config_kwargs.update(kwargs)
    return config_lib.BuildConfig(**config_kwargs)


def _NewBuilderRun(options=None, config=None):
    """Create a BuilderRun objection from options and config values.

    Args:
        options: Specify options or default to DEFAULT_OPTIONS.
        config: Specify build config or default to DEFAULT_CONFIG.

    Returns:
        BuilderRun object.
    """
    manager = parallel_unittest.FakeMultiprocessManager()
    options = options or DEFAULT_OPTIONS
    config = config or DEFAULT_CONFIG
    site_config = config_lib_unittest.MockSiteConfig()
    site_config[config.name] = config

    return cbuildbot_run.BuilderRun(options, site_config, config, manager)


class GetBaseUploadURITest(cros_test_lib.TestCase):
    """Test the GetBaseUploadURI function."""

    ARCHIVE_BASE = "/tmp/the/archive/base"
    BOT_ID = "TheNewBotId"

    def setUp(self) -> None:
        self.cfg = DEFAULT_CONFIG

    def _GetBaseUploadURI(self, *args, **kwargs):
        """Test GetBaseUploadURI with archive_base and no bot_id."""
        return archive_lib.GetBaseUploadURI(self.cfg, *args, **kwargs)

    def testArchiveBase(self) -> None:
        expected_result = "%s/%s" % (self.ARCHIVE_BASE, DEFAULT_BOT_NAME)
        result = self._GetBaseUploadURI(archive_base=self.ARCHIVE_BASE)
        self.assertEqual(expected_result, result)

    def testArchiveBaseBotId(self) -> None:
        expected_result = "%s/%s" % (self.ARCHIVE_BASE, self.BOT_ID)
        result = self._GetBaseUploadURI(
            archive_base=self.ARCHIVE_BASE, bot_id=self.BOT_ID
        )
        self.assertEqual(expected_result, result)

    def testBotId(self) -> None:
        expected_result = "%s/%s" % (
            config_lib.GetSiteParams().ARCHIVE_URL,
            self.BOT_ID,
        )
        result = self._GetBaseUploadURI(bot_id=self.BOT_ID)
        self.assertEqual(expected_result, result)

    def testDefaultGSPath(self) -> None:
        """Test GetBaseUploadURI with default gs_path value in config."""
        self.cfg = _ExtendDefaultConfig(gs_path=config_lib.GS_PATH_DEFAULT)

        # Test without bot_id.
        expected_result = "%s/%s" % (
            config_lib.GetSiteParams().ARCHIVE_URL,
            DEFAULT_BOT_NAME,
        )
        result = self._GetBaseUploadURI()
        self.assertEqual(expected_result, result)

        # Test with bot_id.
        expected_result = "%s/%s" % (
            config_lib.GetSiteParams().ARCHIVE_URL,
            self.BOT_ID,
        )
        result = self._GetBaseUploadURI(bot_id=self.BOT_ID)
        self.assertEqual(expected_result, result)

    def testOverrideGSPath(self) -> None:
        """Test GetBaseUploadURI with default gs_path value in config."""
        self.cfg = _ExtendDefaultConfig(gs_path="gs://funkytown/foo/bar")

        # Test without bot_id.
        expected_result = "gs://funkytown/foo/bar/TheCoolBot"
        result = self._GetBaseUploadURI()
        self.assertEqual(expected_result, result)

        # Test with bot_id.
        expected_result = "gs://funkytown/foo/bar/TheNewBotId"
        result = self._GetBaseUploadURI(bot_id=self.BOT_ID)
        self.assertEqual(expected_result, result)


class ArchiveTest(cros_test_lib.TestCase):
    """Test the Archive class."""

    _VERSION = "6543.2.1"

    def _GetAttributeValue(self, attr, options=None, config=None):
        with mock.patch.object(
            cbuildbot_run._BuilderRunBase, "GetVersion"
        ) as m:
            m.return_value = self._VERSION

            run = _NewBuilderRun(options, config)
            return getattr(run.GetArchive(), attr)

    def testVersion(self) -> None:
        value = self._GetAttributeValue("version")
        self.assertEqual(self._VERSION, value)

    def testVersionNotReady(self) -> None:
        run = _NewBuilderRun()
        self.assertRaises(AttributeError, getattr, run, "version")

    def testArchivePathTrybot(self) -> None:
        options = _ExtendDefaultOptions(buildbot=False)
        value = self._GetAttributeValue("archive_path", options=options)
        expected_value = "%s/%s/%s/%s" % (
            DEFAULT_BUILDROOT,
            archive_lib.Archive._TRYBOT_ARCHIVE,
            DEFAULT_BOT_NAME,
            self._VERSION,
        )
        self.assertEqual(expected_value, value)

    def testArchivePathBuildbot(self) -> None:
        value = self._GetAttributeValue("archive_path")
        expected_value = "%s/%s/%s/%s" % (
            DEFAULT_BUILDROOT,
            archive_lib.Archive._BUILDBOT_ARCHIVE,
            DEFAULT_BOT_NAME,
            self._VERSION,
        )
        self.assertEqual(expected_value, value)

    def testUploadUri(self) -> None:
        value = self._GetAttributeValue("upload_url")
        expected_value = "%s/%s/%s" % (
            DEFAULT_ARCHIVE_BASE,
            DEFAULT_BOT_NAME,
            self._VERSION,
        )
        self.assertEqual(expected_value, value)

    def testDownloadURLBuildbot(self) -> None:
        value = self._GetAttributeValue("download_url")
        expected_value = "%s%s/%s/%s" % (
            gs_urls_util.PRIVATE_BASE_HTTPS_DOWNLOAD_URL,
            DEFAULT_ARCHIVE_PREFIX,
            DEFAULT_BOT_NAME,
            self._VERSION,
        )
        self.assertEqual(expected_value, value)

    def testDownloadURLFileBuildbot(self) -> None:
        value = self._GetAttributeValue("download_url_file")
        expected_value = "%s%s/%s/%s" % (
            gs_urls_util.PRIVATE_BASE_HTTPS_URL,
            DEFAULT_ARCHIVE_PREFIX,
            DEFAULT_BOT_NAME,
            self._VERSION,
        )
        self.assertEqual(expected_value, value)
