# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import io
import logging
import mock
import os
import platform
import shutil
import tempfile
import time
import unittest
import yaml

from mobly import config_parser
from mobly import records
from mobly import test_runner

from tests.lib import mock_controller
from tests.lib import integration_test
from tests.lib import teardown_class_failure_test

if platform.system() == 'Windows':
    import win32file
    from win32com import client


class OutputTest(unittest.TestCase):
    """This test class has unit tests for the implementation of Mobly's output
    files.
    """
    def setUp(self):
        self.tmp_dir = tempfile.mkdtemp()
        self.base_mock_test_config = config_parser.TestRunConfig()
        self.base_mock_test_config.testbed_name = 'SampleTestBed'
        self.base_mock_test_config.controller_configs = {}
        self.base_mock_test_config.user_params = {
            'icecream': 42,
            'extra_param': 'haha'
        }
        self.base_mock_test_config.log_path = self.tmp_dir
        self.log_dir = self.base_mock_test_config.log_path
        self.testbed_name = self.base_mock_test_config.testbed_name

    def tearDown(self):
        shutil.rmtree(self.tmp_dir)

    def create_mock_test_config(self, base_mock_test_config):
        mock_test_config = base_mock_test_config.copy()
        mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
        my_config = [{
            'serial': 'xxxx',
            'magic': 'Magic1'
        }, {
            'serial': 'xxxx',
            'magic': 'Magic2'
        }]
        mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
        return mock_test_config

    def get_output_logs(self, output_dir):
        summary_file_path = os.path.join(output_dir,
                                         records.OUTPUT_FILE_SUMMARY)
        debug_log_path = os.path.join(output_dir,
                                      records.OUTPUT_FILE_DEBUG_LOG)
        info_log_path = os.path.join(output_dir, records.OUTPUT_FILE_INFO_LOG)
        return (summary_file_path, debug_log_path, info_log_path)

    def assert_output_logs_exist(self, output_dir):
        (summary_file_path, debug_log_path,
         info_log_path) = self.get_output_logs(output_dir)
        self.assertTrue(os.path.isfile(summary_file_path))
        self.assertTrue(os.path.isfile(debug_log_path))
        self.assertTrue(os.path.isfile(info_log_path))
        return (summary_file_path, debug_log_path, info_log_path)

    def assert_log_contents(self, log_path, whitelist=[], blacklist=[]):
        with io.open(log_path, 'r', encoding='utf-8') as f:
            content = f.read()
            for item in whitelist:
                self.assertIn(item, content)
            for item in blacklist:
                self.assertNotIn(item, content)

    def test_yields_logging_path(self):
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger() as log_path:
            self.assertEqual(log_path, logging.log_path)

    @unittest.skipIf(platform.system() == 'Windows',
                     'Symlinks are usually specific to Unix operating systems')
    def test_symlink(self):
        """Verifies the symlink is created and links properly."""
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger():
            pass
        symlink = os.path.join(self.log_dir, self.testbed_name, 'latest')
        self.assertEqual(os.readlink(symlink), logging.log_path)

    @unittest.skipIf(platform.system() != 'Windows',
                     'Shortcuts are specific to Windows operating systems')
    def test_shortcut(self):
        """Verifies the shortcut is created and links properly."""
        shortcut_path = os.path.join(self.log_dir, self.testbed_name,
                                     'latest.lnk')
        shell = client.Dispatch("WScript.Shell")
        shortcut = shell.CreateShortCut(shortcut_path)
        self.assertFalse(shortcut.Targetpath)
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger():
            pass
        shortcut = shell.CreateShortCut(shortcut_path)
        # Normalize paths for case and truncation
        normalized_shortcut_path = os.path.normcase(
            win32file.GetLongPathName(shortcut.Targetpath))
        normalized_logger_path = os.path.normcase(
            win32file.GetLongPathName(logging.log_path))
        self.assertEqual(normalized_shortcut_path, normalized_logger_path)

    @mock.patch('mobly.utils.create_alias')
    def test_mobly_logger_with_default_latest_log_alias(
            self, mock_create_alias):
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger():
            pass
        expected_alias_dir = os.path.join(self.log_dir, self.testbed_name,
                                          'latest')
        mock_create_alias.assert_called_once_with(logging.log_path,
                                                  expected_alias_dir)

    @mock.patch('mobly.utils.create_alias')
    def test_mobly_logger_with_custom_latest_log_alias(self,
                                                       mock_create_alias):
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger(alias='history'):
            pass
        expected_alias_dir = os.path.join(self.log_dir, self.testbed_name,
                                          'history')
        mock_create_alias.assert_called_once_with(logging.log_path,
                                                  expected_alias_dir)

    @mock.patch('mobly.utils.create_alias')
    def test_mobly_logger_skips_latest_log_alias_when_none(
            self, mock_create_alias):
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger(alias=None):
            pass
        mock_create_alias.asset_not_called()

    @mock.patch('mobly.utils.create_alias')
    def test_mobly_logger_skips_latest_log_alias_when_empty(
            self, mock_create_alias):
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger(alias=''):
            pass
        mock_create_alias.asset_not_called()

    def test_logging_before_run(self):
        """Verifies the expected output files from a test run.

        * Files are correctly created.
        * Basic sanity checks of each output file.
        """
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        info_uuid = 'e098d4ff-4e90-4e08-b369-aa84a7ef90ec'
        debug_uuid = 'c6f1474e-960a-4df8-8305-1c5b8b905eca'
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger():
            logging.info(info_uuid)
            logging.debug(debug_uuid)
            tr.add_test_class(mock_test_config,
                              integration_test.IntegrationTest)
            tr.run()
        output_dir = logging.log_path
        (summary_file_path, debug_log_path,
         info_log_path) = self.assert_output_logs_exist(output_dir)
        self.assert_log_contents(debug_log_path,
                                 whitelist=[debug_uuid, info_uuid])
        self.assert_log_contents(info_log_path,
                                 whitelist=[info_uuid],
                                 blacklist=[debug_uuid])

    @mock.patch('mobly.logger.get_log_file_timestamp',
                side_effect=str(time.time()))
    def test_run_twice_for_two_sets_of_logs(self, mock_timestamp):
        """Verifies the expected output files from a test run.

        * Files are correctly created.
        * Basic sanity checks of each output file.
        """
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        tr.add_test_class(mock_test_config, integration_test.IntegrationTest)
        with tr.mobly_logger():
            tr.run()
        output_dir1 = logging.log_path
        with tr.mobly_logger():
            tr.run()
        output_dir2 = logging.log_path
        self.assertNotEqual(output_dir1, output_dir2)
        self.assert_output_logs_exist(output_dir1)
        self.assert_output_logs_exist(output_dir2)

    @mock.patch('mobly.logger.get_log_file_timestamp',
                side_effect=str(time.time()))
    def test_teardown_erases_logs(self, mock_timestamp):
        """Verifies the expected output files from a test run.

        * Files are correctly created.
        * Basic sanity checks of each output file.
        """
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        info_uuid1 = '0c3ebb06-700d-496e-b015-62652da9e451'
        debug_uuid1 = '0c3ebb06-700d-496e-b015-62652da9e451'
        info_uuid2 = '484ef7db-f2dd-4b76-a126-c2f263e3808c'
        debug_uuid2 = 'd564da87-c42f-49c3-b0bf-18fa97cf0218'
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)

        with tr.mobly_logger():
            logging.info(info_uuid1)
            logging.debug(debug_uuid1)
        output_dir1 = logging.log_path

        with tr.mobly_logger():
            logging.info(info_uuid2)
            logging.debug(debug_uuid2)
        output_dir2 = logging.log_path

        self.assertNotEqual(output_dir1, output_dir2)

        (summary_file_path1, debug_log_path1,
         info_log_path1) = self.get_output_logs(output_dir1)
        (summary_file_path2, debug_log_path2,
         info_log_path2) = self.get_output_logs(output_dir2)

        self.assert_log_contents(debug_log_path1,
                                 whitelist=[debug_uuid1, info_uuid1],
                                 blacklist=[info_uuid2, debug_uuid2])
        self.assert_log_contents(debug_log_path2,
                                 whitelist=[debug_uuid2, info_uuid2],
                                 blacklist=[info_uuid1, debug_uuid1])

    def test_basic_output(self):
        """Verifies the expected output files from a test run.

        * Files are correctly created.
        * Basic sanity checks of each output file.
        """
        mock_test_config = self.create_mock_test_config(
            self.base_mock_test_config)
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger():
            tr.add_test_class(mock_test_config,
                              integration_test.IntegrationTest)
            tr.run()
        output_dir = logging.log_path
        (summary_file_path, debug_log_path,
         info_log_path) = self.assert_output_logs_exist(output_dir)
        summary_entries = []
        with io.open(summary_file_path, 'r', encoding='utf-8') as f:
            for entry in yaml.safe_load_all(f):
                self.assertTrue(entry['Type'])
                summary_entries.append(entry)
        self.assert_log_contents(debug_log_path, whitelist=['DEBUG', 'INFO'])
        self.assert_log_contents(info_log_path,
                                 whitelist=['INFO'],
                                 blacklist=['DEBUG'])

    def test_teardown_class_output(self):
        """Verifies the summary file includes the failure record for
        teardown_class.
        """
        mock_test_config = self.base_mock_test_config.copy()
        tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
        with tr.mobly_logger():
            tr.add_test_class(
                mock_test_config,
                teardown_class_failure_test.TearDownClassFailureTest)
            tr.run()
        output_dir = logging.log_path
        summary_file_path = os.path.join(output_dir,
                                         records.OUTPUT_FILE_SUMMARY)
        found = False
        with io.open(summary_file_path, 'r', encoding='utf-8') as f:
            raw_content = f.read()
            f.seek(0)
            for entry in yaml.safe_load_all(f):
                if (entry['Type'] == 'Record'
                        and entry[records.TestResultEnums.RECORD_NAME] ==
                        'teardown_class'):
                    found = True
                    break
            self.assertTrue(
                found,
                'No record for teardown_class found in the output file:\n %s' %
                raw_content)


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