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

"""Unittests for Binhost operations."""

import os
from pathlib import Path
from unittest import mock

from chromite.api import api_config
from chromite.api.controller import binhost
from chromite.api.gen.chromite.api import binhost_pb2
from chromite.api.gen.chromiumos import common_pb2
from chromite.lib import binpkg
from chromite.lib import chroot_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.service import binhost as binhost_service


class GetBinhostsTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
    """Unittests for GetBinhosts."""

    def setUp(self) -> None:
        self.response = binhost_pb2.BinhostGetResponse()

    def testValidateOnly(self) -> None:
        """Check that a validate only call does not execute any logic."""
        patch = self.PatchObject(binhost_service, "GetBinhosts")

        request = binhost_pb2.BinhostGetRequest()
        request.build_target.name = "target"
        binhost.GetBinhosts(request, self.response, self.validate_only_config)
        patch.assert_not_called()

    def testMockCall(self) -> None:
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(binhost_service, "GetBinhosts")

        request = binhost_pb2.BinhostGetRequest()
        request.build_target.name = "target"

        binhost.GetBinhosts(request, self.response, self.mock_call_config)

        self.assertEqual(len(self.response.binhosts), 1)
        self.assertEqual(self.response.binhosts[0].package_index, "Packages")
        patch.assert_not_called()

    def testGetBinhosts(self) -> None:
        """GetBinhosts calls service with correct args."""
        # pylint: disable=line-too-long
        binhost_list = [
            f"{constants.TRASH_BUCKET}/board/amd64-generic/paladin-R66-17.0.0-rc2/packages/",
            f"{constants.TRASH_BUCKET}/board/eve/paladin-R66-17.0.0-rc2/packages/",
        ]
        # pylint: enable=line-too-long
        get_binhost = self.PatchObject(
            binhost_service, "GetBinhosts", return_value=binhost_list
        )

        request = binhost_pb2.BinhostGetRequest()
        request.build_target.name = "target"

        binhost.GetBinhosts(request, self.response, self.api_config)

        self.assertEqual(len(self.response.binhosts), 2)
        self.assertEqual(self.response.binhosts[0].package_index, "Packages")
        get_binhost.assert_called_once_with(mock.ANY)


class GetPrivatePrebuiltAclArgsTest(
    cros_test_lib.MockTestCase, api_config.ApiConfigMixin
):
    """Unittests for GetPrivatePrebuiltAclArgs."""

    def setUp(self) -> None:
        self.response = binhost_pb2.AclArgsResponse()

    def testValidateOnly(self) -> None:
        """Check that a validate only call does not execute any logic."""
        patch = self.PatchObject(binhost_service, "GetPrebuiltAclArgs")

        request = binhost_pb2.AclArgsRequest()
        request.build_target.name = "target"
        binhost.GetPrivatePrebuiltAclArgs(
            request, self.response, self.validate_only_config
        )
        patch.assert_not_called()

    def testMockCall(self) -> None:
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(binhost_service, "GetPrebuiltAclArgs")

        request = binhost_pb2.AclArgsRequest()
        request.build_target.name = "target"

        binhost.GetPrivatePrebuiltAclArgs(
            request, self.response, self.mock_call_config
        )

        self.assertEqual(len(self.response.args), 1)
        self.assertEqual(self.response.args[0].arg, "-g")
        self.assertEqual(self.response.args[0].value, "group1:READ")
        patch.assert_not_called()

    def testGetPrivatePrebuiltAclArgs(self) -> None:
        """GetPrivatePrebuildAclsArgs calls service with correct args."""
        argvalue_list = [["-g", "group1:READ"]]
        get_binhost = self.PatchObject(
            binhost_service, "GetPrebuiltAclArgs", return_value=argvalue_list
        )

        request = binhost_pb2.AclArgsRequest()
        request.build_target.name = "target"

        binhost.GetPrivatePrebuiltAclArgs(
            request, self.response, self.api_config
        )

        self.assertEqual(len(self.response.args), 1)
        self.assertEqual(self.response.args[0].arg, "-g")
        self.assertEqual(self.response.args[0].value, "group1:READ")
        get_binhost.assert_called_once_with(mock.ANY)


class PrepareBinhostUploadsTest(
    cros_test_lib.MockTestCase, api_config.ApiConfigMixin
):
    """Unittests for PrepareBinhostUploads."""

    def setUp(self) -> None:
        self.PatchObject(
            binhost_service,
            "GetPrebuiltsRoot",
            return_value="/build/target/packages",
        )
        self.PatchObject(
            binhost_service,
            "GetPrebuiltsFiles",
            return_value=["foo.tbz2", "bar.tbz2"],
        )
        self.PatchObject(
            binhost_service,
            "UpdatePackageIndex",
            return_value="/build/target/packages/Packages",
        )

        self.response = binhost_pb2.PrepareBinhostUploadsResponse()

    def testValidateOnly(self) -> None:
        """Check that a validate only call does not execute any logic."""
        patch = self.PatchObject(binhost_service, "GetPrebuiltsRoot")

        request = binhost_pb2.PrepareBinhostUploadsRequest()
        request.build_target.name = "target"
        request.uri = "gs://chromeos-prebuilt/target"
        rc = binhost.PrepareBinhostUploads(
            request, self.response, self.validate_only_config
        )
        patch.assert_not_called()
        self.assertEqual(rc, 0)

    def testMockCall(self) -> None:
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(binhost_service, "GetPrebuiltsRoot")

        request = binhost_pb2.PrepareBinhostUploadsRequest()
        request.build_target.name = "target"
        request.uri = "gs://chromeos-prebuilt/target"
        rc = binhost.PrepareBinhostUploads(
            request, self.response, self.mock_call_config
        )
        self.assertEqual(self.response.uploads_dir, "/upload/directory")
        self.assertEqual(self.response.upload_targets[0].path, "upload_target")
        patch.assert_not_called()
        self.assertEqual(rc, 0)

    def testPrepareBinhostUploads(self) -> None:
        """PrepareBinhostUploads returns Packages and tar files."""
        request = binhost_pb2.PrepareBinhostUploadsRequest()
        request.build_target.name = "target"
        request.uri = "gs://chromeos-prebuilt/target"
        binhost.PrepareBinhostUploads(request, self.response, self.api_config)
        self.assertEqual(self.response.uploads_dir, "/build/target/packages")
        self.assertCountEqual(
            [ut.path for ut in self.response.upload_targets],
            ["Packages", "foo.tbz2", "bar.tbz2"],
        )

    def testPrepareBinhostUploadsNonGsUri(self) -> None:
        """PrepareBinhostUploads dies when URI does not point to GS."""
        request = binhost_pb2.PrepareBinhostUploadsRequest()
        request.build_target.name = "target"
        request.uri = "https://foo.bar"
        with self.assertRaises(ValueError):
            binhost.PrepareBinhostUploads(
                request, self.response, self.api_config
            )


class UpdatePackageIndexTest(
    cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
):
    """Unit tests for BinhostService/UpdatePackageIndex."""

    def setUp(self) -> None:
        self._original_pkg_index = binpkg.PackageIndex()
        self._original_pkg_index.header["A"] = "B"
        self._original_pkg_index.packages = [
            {
                "CPV": "foo/bar",
                "KEY": "value",
            },
            {
                "CPV": "cat/pkg",
                "KEY": "also_value",
            },
        ]
        self._pkg_index_fp = os.path.join(
            self.tempdir,
            "path/to/packages/Packages",
        )

    def _write_original_package_index(self) -> None:
        """Write the package index to the tempdir.

        Note that if an request specifies location=INSIDE, then they will
        not be able to find the written file, since the tempdir isn't actually
        inside a chroot.
        """
        osutils.Touch(self._pkg_index_fp, makedirs=True)
        self._original_pkg_index.WriteFile(self._pkg_index_fp)

    def testValidateOnly(self) -> None:
        """Check that a validate only call does not execute any logic."""
        self._write_original_package_index()
        patch = self.PatchObject(binpkg.PackageIndex, "ReadFilePath")
        request = binhost_pb2.UpdatePackageIndexRequest(
            package_index_file=common_pb2.Path(
                path=self._pkg_index_fp,
                location=common_pb2.Path.Location.OUTSIDE,
            ),
            set_upload_location=True,
        )
        response = binhost_pb2.UpdatePackageIndexResponse()
        binhost.UpdatePackageIndex(request, response, self.validate_only_config)
        patch.assert_not_called()

    def testMustProvideSomeCommand(self) -> None:
        """Test that an error is raised if no update types are specified."""
        self._write_original_package_index()
        request = binhost_pb2.UpdatePackageIndexRequest(
            package_index_file=common_pb2.Path(
                path=self._pkg_index_fp,
                location=common_pb2.Path.OUTSIDE,
            ),
            uri="gs://chromeos-prebuilt/board/amd64-host/packages",
        )
        response = binhost_pb2.UpdatePackageIndexResponse()
        with self.assertRaises(cros_build_lib.DieSystemExit):
            binhost.UpdatePackageIndex(request, response, self.api_config)

    def testSetUploadLocation(self) -> None:
        """Test setting the package upload location in the index file.

        This test includes correctly parsing the input uri.
        """
        # Arrange
        self._write_original_package_index()

        # Act
        request = binhost_pb2.UpdatePackageIndexRequest(
            package_index_file=common_pb2.Path(
                path=self._pkg_index_fp,
                location=common_pb2.Path.Location.OUTSIDE,
            ),
            set_upload_location=True,
            uri="gs://chromeos-prebuilt/board/amd64-host/packages/",
        )
        response = binhost_pb2.UpdatePackageIndexResponse()
        binhost.UpdatePackageIndex(request, response, self.api_config)

        # Assert
        new_pkg_index = binpkg.PackageIndex()
        new_pkg_index.ReadFilePath(self._pkg_index_fp)
        self.assertEqual(new_pkg_index.header["URI"], "gs://chromeos-prebuilt")
        self.assertDictEqual(
            new_pkg_index.packages[0],
            {
                "CPV": "cat/pkg",
                "KEY": "also_value",
                "PATH": "board/amd64-host/packages/cat/pkg.tbz2",
            },
        )
        self.assertDictEqual(
            new_pkg_index.packages[1],
            {
                "CPV": "foo/bar",
                "KEY": "value",
                "PATH": "board/amd64-host/packages/foo/bar.tbz2",
            },
        )


class SetBinhostTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
    """Unittests for SetBinhost."""

    def setUp(self) -> None:
        self.response = binhost_pb2.SetBinhostResponse()

    def testValidateOnly(self) -> None:
        """Check that a validate only call does not execute any logic."""
        patch = self.PatchObject(binhost_service, "SetBinhost")

        request = binhost_pb2.SetBinhostRequest()
        request.build_target.name = "target"
        request.key = binhost_pb2.POSTSUBMIT_BINHOST
        request.uri = "gs://chromeos-prebuilt/target"
        binhost.SetBinhost(request, self.response, self.validate_only_config)
        patch.assert_not_called()

    def testMockCall(self) -> None:
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(binhost_service, "SetBinhost")

        request = binhost_pb2.SetBinhostRequest()
        request.build_target.name = "target"
        request.key = binhost_pb2.POSTSUBMIT_BINHOST
        request.uri = "gs://chromeos-prebuilt/target"
        request.max_uris = 4
        binhost.SetBinhost(request, self.response, self.mock_call_config)
        patch.assert_not_called()
        self.assertEqual(self.response.output_file, "/path/to/BINHOST.conf")

    def testSetBinhost(self) -> None:
        """SetBinhost calls service with correct args."""
        set_binhost = self.PatchObject(
            binhost_service, "SetBinhost", return_value="/path/to/BINHOST.conf"
        )

        request = binhost_pb2.SetBinhostRequest()
        request.build_target.name = "target"
        request.private = True
        request.key = binhost_pb2.POSTSUBMIT_BINHOST
        request.uri = "gs://chromeos-prebuilt/target"
        request.max_uris = 4
        binhost.SetBinhost(request, self.response, self.api_config)

        self.assertEqual(self.response.output_file, "/path/to/BINHOST.conf")
        set_binhost.assert_called_once_with(
            "target",
            "POSTSUBMIT_BINHOST",
            "gs://chromeos-prebuilt/target",
            private=True,
            max_uris=4,
        )


class GetBinhostConfPathTest(
    cros_test_lib.MockTestCase, api_config.ApiConfigMixin
):
    """Unittests for GetBinhostConfPath."""

    def setUp(self) -> None:
        self.response = binhost_pb2.GetBinhostConfPathResponse()

    def testValidateOnly(self) -> None:
        """Check that a validate only call does not execute any logic."""
        patch = self.PatchObject(binhost_service, "GetBinhostConfPath")

        request = binhost_pb2.GetBinhostConfPathRequest()
        request.build_target.name = "target"
        request.key = binhost_pb2.POSTSUBMIT_BINHOST
        binhost.GetBinhostConfPath(
            request, self.response, self.validate_only_config
        )
        patch.assert_not_called()

    def testMockCall(self) -> None:
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(binhost_service, "GetBinhostConfPath")

        request = binhost_pb2.GetBinhostConfPathRequest()
        request.build_target.name = "target"
        request.key = binhost_pb2.POSTSUBMIT_BINHOST
        binhost.GetBinhostConfPath(
            request, self.response, self.mock_call_config
        )
        patch.assert_not_called()
        self.assertEqual(self.response.conf_path, "/path/to/BINHOST.conf")

    def testGetBinhostConfPath(self) -> None:
        """GetBinhostConfPath calls service with correct args."""
        get_binhost_conf_path = self.PatchObject(
            binhost_service,
            "GetBinhostConfPath",
            return_value="/path/to/BINHOST.conf",
        )
        request = binhost_pb2.GetBinhostConfPathRequest()
        request.build_target.name = "target"
        request.private = True
        request.key = binhost_pb2.POSTSUBMIT_BINHOST
        binhost.GetBinhostConfPath(request, self.response, self.api_config)

        self.assertEqual(self.response.conf_path, "/path/to/BINHOST.conf")
        get_binhost_conf_path.assert_called_once_with(
            "target",
            "POSTSUBMIT_BINHOST",
            True,
        )


class RegenBuildCacheTest(
    cros_test_lib.MockTestCase, api_config.ApiConfigMixin
):
    """Unittests for RegenBuildCache."""

    def setUp(self) -> None:
        self.response = binhost_pb2.RegenBuildCacheResponse()

    def testValidateOnly(self) -> None:
        """Check that a validate only call does not execute any logic."""
        patch = self.PatchObject(binhost_service, "RegenBuildCache")

        request = binhost_pb2.RegenBuildCacheRequest()
        request.overlay_type = binhost_pb2.OVERLAYTYPE_BOTH
        binhost.RegenBuildCache(
            request, self.response, self.validate_only_config
        )
        patch.assert_not_called()

    def testMockCall(self) -> None:
        """Test a mock call does not execute logic, returns mocked value."""
        patch = self.PatchObject(binhost_service, "RegenBuildCache")

        request = binhost_pb2.RegenBuildCacheRequest()
        request.overlay_type = binhost_pb2.OVERLAYTYPE_BOTH
        binhost.RegenBuildCache(request, self.response, self.mock_call_config)
        patch.assert_not_called()
        self.assertEqual(len(self.response.modified_overlays), 1)
        self.assertEqual(
            self.response.modified_overlays[0].path, "/path/to/BuildCache"
        )

    def testRegenBuildCache(self) -> None:
        """RegenBuildCache calls service with the correct args."""
        regen_cache = self.PatchObject(binhost_service, "RegenBuildCache")

        request = binhost_pb2.RegenBuildCacheRequest()
        request.overlay_type = binhost_pb2.OVERLAYTYPE_BOTH

        binhost.RegenBuildCache(request, self.response, self.api_config)
        regen_cache.assert_called_once_with(mock.ANY, "both")

    def testRequiresOverlayType(self) -> None:
        """RegenBuildCache dies if overlay_type not specified."""
        regen_cache = self.PatchObject(binhost_service, "RegenBuildCache")

        request = binhost_pb2.RegenBuildCacheRequest()
        request.overlay_type = binhost_pb2.OVERLAYTYPE_UNSPECIFIED

        with self.assertRaises(cros_build_lib.DieSystemExit):
            binhost.RegenBuildCache(request, self.response, self.api_config)
        regen_cache.assert_not_called()


class PrepareChromeBinhostUploadsTest(
    cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
):
    """Tests for BinhostService/PrepareChromeBinhostUploads."""

    def setUp(self) -> None:
        self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
        self.create_chrome_package_index_mock = self.PatchObject(
            binhost_service, "CreateChromePackageIndex"
        )

        self.chroot = chroot_lib.Chroot(
            path=self.tempdir / "chroot",
            out_path=self.tempdir / "out",
        )
        self.sysroot_path = "build/target"
        self.uploads_dir = self.tempdir / "uploads_dir"
        self.request = binhost_pb2.PrepareChromeBinhostUploadsRequest()
        self.request.uri = "gs://chromeos-prebuilt/target"
        self.request.chroot.path = str(self.chroot.path)
        self.request.chroot.out_path = str(self.chroot.out_path)
        self.request.sysroot.path = self.sysroot_path
        self.request.uploads_dir = str(self.uploads_dir)
        self.response = binhost_pb2.PrepareChromeBinhostUploadsResponse()

        self.packages_path = Path(
            self.chroot.full_path(self.sysroot_path, "packages")
        )
        self.chrome_packages_path = self.packages_path / constants.CHROME_CN
        osutils.Touch(
            self.chrome_packages_path / "chromeos-chrome-100-r1.tbz2",
            makedirs=True,
        )
        osutils.Touch(
            self.chrome_packages_path / "chrome-icu-100-r1.tbz2",
            makedirs=True,
        )
        osutils.Touch(
            self.chrome_packages_path / "chromeos-lacros-100-r1.tbz2",
            makedirs=True,
        )

    def testValidateOnly(self) -> None:
        """Check that a validate only call does not execute any logic."""
        binhost.PrepareChromeBinhostUploads(
            self.request, self.response, self.validate_only_config
        )

        self.create_chrome_package_index_mock.assert_not_called()

    def testMockCall(self) -> None:
        """Test a mock call does not execute logic, returns mocked value."""
        binhost.PrepareChromeBinhostUploads(
            self.request, self.response, self.mock_call_config
        )

        self.assertEqual(len(self.response.upload_targets), 4)
        self.assertEqual(self.response.upload_targets[3].path, "Packages")
        self.create_chrome_package_index_mock.assert_not_called()

    def testChromeUpload(self) -> None:
        """Test uploads of Chrome prebuilts."""
        expected_upload_targets = [
            "chromeos-base/chromeos-chrome-100-r1.tbz2",
            "chromeos-base/chrome-icu-100-r1.tbz2",
            "chromeos-base/chromeos-lacros-100-r1.tbz2",
        ]
        self.create_chrome_package_index_mock.return_value = (
            expected_upload_targets
        )

        binhost.PrepareChromeBinhostUploads(
            self.request, self.response, self.api_config
        )

        self.assertCountEqual(
            [target.path for target in self.response.upload_targets],
            expected_upload_targets + ["Packages"],
        )

    def testPrepareBinhostUploadsNonGsUri(self) -> None:
        """PrepareBinhostUploads dies when URI does not point to GS."""
        self.request.uri = "https://foo.bar"

        with self.assertRaises(ValueError):
            binhost.PrepareChromeBinhostUploads(
                self.request, self.response, self.api_config
            )
