#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 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.

"""Download image unittest."""


import os
import unittest
import unittest.mock as mock

from cros_utils import command_executer
from cros_utils import logger
import download_images
import test_flag


MOCK_LOGGER = logger.GetLogger(log_dir="", mock=True)


class ImageDownloaderTestcast(unittest.TestCase):
    """The image downloader test class."""

    def __init__(self, *args, **kwargs):
        super(ImageDownloaderTestcast, self).__init__(*args, **kwargs)
        self.called_download_image = False
        self.called_uncompress_image = False
        self.called_get_build_id = False
        self.called_download_autotest_files = False
        self.called_download_debug_file = False

    @mock.patch.object(os, "makedirs")
    @mock.patch.object(os.path, "exists")
    def test_download_image(self, mock_path_exists, mock_mkdirs):

        # Set mock and test values.
        mock_cmd_exec = mock.Mock(spec=command_executer.CommandExecuter)
        test_chroot = "/usr/local/home/chromeos"
        test_build_id = "lumpy-release/R36-5814.0.0"
        image_path = (
            "gs://chromeos-image-archive/%s/chromiumos_test_image.tar.xz"
            % test_build_id
        )

        downloader = download_images.ImageDownloader(
            logger_to_use=MOCK_LOGGER, cmd_exec=mock_cmd_exec
        )

        # Set os.path.exists to always return False and run downloader
        mock_path_exists.return_value = False
        test_flag.SetTestMode(True)
        self.assertRaises(
            download_images.MissingImage,
            downloader.DownloadImage,
            test_chroot,
            test_build_id,
            image_path,
        )

        # Verify os.path.exists was called twice, with proper arguments.
        self.assertEqual(mock_path_exists.call_count, 2)
        mock_path_exists.assert_called_with(
            "/usr/local/home/chromeos/chroot/tmp/lumpy-release/"
            "R36-5814.0.0/chromiumos_test_image.bin"
        )
        mock_path_exists.assert_any_call(
            "/usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0"
        )

        # Verify we called os.mkdirs
        self.assertEqual(mock_mkdirs.call_count, 1)
        mock_mkdirs.assert_called_with(
            "/usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0"
        )

        # Verify we called RunCommand once, with proper arguments.
        self.assertEqual(mock_cmd_exec.RunCommand.call_count, 1)
        expected_args = (
            "/usr/local/home/chromeos/src/chromium/depot_tools/gsutil.py "
            "cp gs://chromeos-image-archive/lumpy-release/R36-5814.0.0/"
            "chromiumos_test_image.tar.xz "
            "/usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0"
        )

        mock_cmd_exec.RunCommand.assert_called_with(expected_args)

        # Reset the velues in the mocks; set os.path.exists to always return True.
        mock_path_exists.reset_mock()
        mock_cmd_exec.reset_mock()
        mock_path_exists.return_value = True

        # Run downloader
        downloader.DownloadImage(test_chroot, test_build_id, image_path)

        # Verify os.path.exists was called twice, with proper arguments.
        self.assertEqual(mock_path_exists.call_count, 2)
        mock_path_exists.assert_called_with(
            "/usr/local/home/chromeos/chroot/tmp/lumpy-release/"
            "R36-5814.0.0/chromiumos_test_image.bin"
        )
        mock_path_exists.assert_any_call(
            "/usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0"
        )

        # Verify we made no RunCommand or ChrootRunCommand calls (since
        # os.path.exists returned True, there was no work do be done).
        self.assertEqual(mock_cmd_exec.RunCommand.call_count, 0)
        self.assertEqual(mock_cmd_exec.ChrootRunCommand.call_count, 0)

    @mock.patch.object(os.path, "exists")
    def test_uncompress_image(self, mock_path_exists):

        # set mock and test values.
        mock_cmd_exec = mock.Mock(spec=command_executer.CommandExecuter)
        test_chroot = "/usr/local/home/chromeos"
        test_build_id = "lumpy-release/R36-5814.0.0"

        downloader = download_images.ImageDownloader(
            logger_to_use=MOCK_LOGGER, cmd_exec=mock_cmd_exec
        )

        # Set os.path.exists to always return False and run uncompress.
        mock_path_exists.return_value = False
        self.assertRaises(
            download_images.MissingImage,
            downloader.UncompressImage,
            test_chroot,
            test_build_id,
        )

        # Verify os.path.exists was called once, with correct arguments.
        self.assertEqual(mock_path_exists.call_count, 1)
        mock_path_exists.assert_called_with(
            "/usr/local/home/chromeos/chroot/tmp/lumpy-release/"
            "R36-5814.0.0/chromiumos_test_image.bin"
        )

        # Verify RunCommand was called twice with correct arguments.
        self.assertEqual(mock_cmd_exec.RunCommand.call_count, 2)
        # Call 1, should have 2 arguments
        self.assertEqual(len(mock_cmd_exec.RunCommand.call_args_list[0]), 2)
        actual_arg = mock_cmd_exec.RunCommand.call_args_list[0][0]
        expected_arg = (
            "cd /usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0 ; "
            "tar -Jxf chromiumos_test_image.tar.xz ",
        )
        self.assertEqual(expected_arg, actual_arg)
        # 2nd arg must be exception handler
        except_handler_string = "RunCommandExceptionHandler.HandleException"
        self.assertTrue(
            except_handler_string
            in repr(mock_cmd_exec.RunCommand.call_args_list[0][1])
        )

        # Call 2, should have 2 arguments
        self.assertEqual(len(mock_cmd_exec.RunCommand.call_args_list[1]), 2)
        actual_arg = mock_cmd_exec.RunCommand.call_args_list[1][0]
        expected_arg = (
            "cd /usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0 ; "
            "rm -f chromiumos_test_image.bin ",
        )
        self.assertEqual(expected_arg, actual_arg)
        # 2nd arg must be empty
        self.assertTrue(
            "{}" in repr(mock_cmd_exec.RunCommand.call_args_list[1][1])
        )

        # Set os.path.exists to always return True and run uncompress.
        mock_path_exists.reset_mock()
        mock_cmd_exec.reset_mock()
        mock_path_exists.return_value = True
        downloader.UncompressImage(test_chroot, test_build_id)

        # Verify os.path.exists was called once, with correct arguments.
        self.assertEqual(mock_path_exists.call_count, 1)
        mock_path_exists.assert_called_with(
            "/usr/local/home/chromeos/chroot/tmp/lumpy-release/"
            "R36-5814.0.0/chromiumos_test_image.bin"
        )

        # Verify RunCommand was not called.
        self.assertEqual(mock_cmd_exec.RunCommand.call_count, 0)

    def test_run(self):

        # Set test arguments
        test_chroot = "/usr/local/home/chromeos"
        test_build_id = "remote/lumpy/latest-dev"
        test_empty_autotest_path = ""
        test_empty_debug_path = ""
        test_autotest_path = "/tmp/autotest"
        test_debug_path = "/tmp/debug"
        download_debug = True

        # Set values to test/check.
        self.called_download_image = False
        self.called_uncompress_image = False
        self.called_get_build_id = False
        self.called_download_autotest_files = False
        self.called_download_debug_file = False

        # Define fake stub functions for Run to call
        def FakeGetBuildID(unused_root, unused_xbuddy_label):
            self.called_get_build_id = True
            return "lumpy-release/R36-5814.0.0"

        def GoodDownloadImage(root, build_id, image_path):
            if root or build_id or image_path:
                pass
            self.called_download_image = True
            return "chromiumos_test_image.bin"

        def BadDownloadImage(root, build_id, image_path):
            if root or build_id or image_path:
                pass
            self.called_download_image = True
            raise download_images.MissingImage("Could not download image")

        def FakeUncompressImage(root, build_id):
            if root or build_id:
                pass
            self.called_uncompress_image = True
            return 0

        def FakeDownloadAutotestFiles(root, build_id):
            if root or build_id:
                pass
            self.called_download_autotest_files = True
            return "autotest"

        def FakeDownloadDebugFile(root, build_id):
            if root or build_id:
                pass
            self.called_download_debug_file = True
            return "debug"

        # Initialize downloader
        downloader = download_images.ImageDownloader(logger_to_use=MOCK_LOGGER)

        # Set downloader to call fake stubs.
        downloader.GetBuildID = FakeGetBuildID
        downloader.UncompressImage = FakeUncompressImage
        downloader.DownloadImage = GoodDownloadImage
        downloader.DownloadAutotestFiles = FakeDownloadAutotestFiles
        downloader.DownloadDebugFile = FakeDownloadDebugFile

        # Call Run.
        image_path, autotest_path, debug_path = downloader.Run(
            test_chroot,
            test_build_id,
            test_empty_autotest_path,
            test_empty_debug_path,
            download_debug,
        )

        # Make sure it called both _DownloadImage and _UncompressImage
        self.assertTrue(self.called_download_image)
        self.assertTrue(self.called_uncompress_image)
        # Make sure it called DownloadAutotestFiles
        self.assertTrue(self.called_download_autotest_files)
        # Make sure it called DownloadDebugFile
        self.assertTrue(self.called_download_debug_file)
        # Make sure it returned an image and autotest path returned from this call
        self.assertTrue(image_path == "chromiumos_test_image.bin")
        self.assertTrue(autotest_path == "autotest")
        self.assertTrue(debug_path == "debug")

        # Call Run with a non-empty autotest and debug path
        self.called_download_autotest_files = False
        self.called_download_debug_file = False

        image_path, autotest_path, debug_path = downloader.Run(
            test_chroot,
            test_build_id,
            test_autotest_path,
            test_debug_path,
            download_debug,
        )

        # Verify that downloadAutotestFiles was not called
        self.assertFalse(self.called_download_autotest_files)
        # Make sure it returned the specified autotest path returned from this call
        self.assertTrue(autotest_path == test_autotest_path)
        # Make sure it returned the specified debug path returned from this call
        self.assertTrue(debug_path == test_debug_path)

        # Reset values; Now use fake stub that simulates DownloadImage failing.
        self.called_download_image = False
        self.called_uncompress_image = False
        self.called_download_autotest_files = False
        self.called_download_debug_file = False
        downloader.DownloadImage = BadDownloadImage

        # Call Run again.
        self.assertRaises(
            download_images.MissingImage,
            downloader.Run,
            test_chroot,
            test_autotest_path,
            test_debug_path,
            test_build_id,
            download_debug,
        )

        # Verify that UncompressImage and downloadAutotestFiles were not called,
        # since _DownloadImage "failed"
        self.assertTrue(self.called_download_image)
        self.assertFalse(self.called_uncompress_image)
        self.assertFalse(self.called_download_autotest_files)
        self.assertFalse(self.called_download_debug_file)


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