#!/usr/bin/env python3
#
# Copyright 2019, The Android Open Source Project
#
# 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.

"""Unittests for native_module_info."""

import logging
import os
import unittest
from unittest import mock

from aidegen import constant
from aidegen.lib import common_util
from aidegen.lib import module_info
from aidegen.lib import native_module_info

import atest

_PATH_TO_MULT_MODULES_WITH_MULTI_ARCH = 'shared/path/to/be/used2'
_TESTABLE_MODULES_WITH_SHARED_PATH = [
    'multiarch', 'multiarch1', 'multiarch2', 'multiarch3', 'multiarch3_32'
]
_REBUILD_TARGET1 = 'android.frameworks.bufferhub@1.0'
_NATIVE_INCLUDES1 = [
    'frameworks/native/include',
    'frameworks/native/libs/ui',
    'out/soong/.intermediates/' + _REBUILD_TARGET1 + '_genc++_headers/gen'
]
_CC_NAME_TO_MODULE_INFO = {
    'multiarch': {
        'path': [
            'shared/path/to/be/used2'
        ],
        'srcs': [
            'shared/path/to/be/used2/multiarch.cpp',
            'out/soong/.intermediates/shared/path/to/be/used2/gen/Iarch.cpp'
        ],
        'local_common_flags': {
            constant.KEY_HEADER: _NATIVE_INCLUDES1
        },
        'module_name': 'multiarch'
    },
    'multiarch1': {
        'path': [
            'shared/path/to/be/used2/arch1'
        ],
        'module_name': 'multiarch1'
    },
    'multiarch2': {
        'path': [
            'shared/path/to/be/used2/arch2'
        ],
        'module_name': 'multiarch2'
    },
    'multiarch3': {
        'path': [
            'shared/path/to/be/used2/arch3'
        ],
        'module_name': 'multiarch3'
    },
    'multiarch3_32': {
        'path': [
            'shared/path/to/be/used2/arch3_32'
        ],
        'module_name': 'multiarch3_32'
    },
    _REBUILD_TARGET1: {
        'path': [
            '/path/to/rebuild'
        ],
        'module_name': _REBUILD_TARGET1
    }
}
_CC_MODULE_INFO = {
    'clang': '${ANDROID_ROOT}/prebuilts/clang/host/linux-x86/bin/clang',
    'clang++': '${ANDROID_ROOT}/prebuilts/clang/host/linux-x86/bin/clang++',
    'modules': _CC_NAME_TO_MODULE_INFO
}


# pylint: disable=protected-access
class NativeModuleInfoUnittests(unittest.TestCase):
    """Unit tests for module_info.py"""

    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    @mock.patch.object(common_util, 'get_related_paths')
    def test_get_module_names_in_targets_paths(self, mock_relpath, mock_load):
        """Test get_module_names_in_targets_paths handling."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        mock_relpath.return_value = (_PATH_TO_MULT_MODULES_WITH_MULTI_ARCH, '')
        result = mod_info.get_module_names_in_targets_paths(['multiarch'])
        self.assertEqual(_TESTABLE_MODULES_WITH_SHARED_PATH, result)

    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_get_module_includes_empty(self, mock_load):
        """Test get_module_includes without include paths."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        result = mod_info.get_module_includes('multiarch1')
        self.assertEqual(set(), result)

    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_get_module_includes_not_empty(self, mock_load):
        """Test get_module_includes with include paths."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        result = mod_info.get_module_includes('multiarch')
        self.assertEqual(set(_NATIVE_INCLUDES1), result)

    @mock.patch.object(logging, 'warning')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_module_need_build_without_mod_info(self, mock_load, mock_warn):
        """Test get_module_includes without module info."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        self.assertFalse(mod_info.is_module_need_build('test_multiarch'))
        self.assertTrue(mock_warn.called)

    @mock.patch.object(logging, 'warning')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_module_need_build_with_mod_info(self, mock_load, mock_warn):
        """Test get_module_includes with module info."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        self.assertFalse(mod_info.is_module_need_build('multiarch1'))
        self.assertFalse(mock_warn.called)

    @mock.patch('native_module_info.NativeModuleInfo._is_include_need_build')
    @mock.patch('native_module_info.NativeModuleInfo._is_source_need_build')
    @mock.patch.object(logging, 'warning')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_module_need_build_with_src_needs(
            self, mock_load, mock_warn, mock_src_need, mock_inc_need):
        """Test get_module_includes with needed build source modules."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        mock_src_need.return_value = True
        mock_inc_need.return_value = False
        self.assertTrue(mod_info.is_module_need_build('multiarch'))
        self.assertFalse(mock_warn.called)

    @mock.patch('native_module_info.NativeModuleInfo._is_include_need_build')
    @mock.patch('native_module_info.NativeModuleInfo._is_source_need_build')
    @mock.patch.object(logging, 'warning')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_module_need_build_with_inc_needs(
            self, mock_load, mock_warn, mock_src_need, mock_inc_need):
        """Test get_module_includes with needed build include modules."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        mock_src_need.return_value = False
        mock_inc_need.return_value = True
        self.assertTrue(mod_info.is_module_need_build('multiarch'))
        self.assertFalse(mock_warn.called)

    @mock.patch('native_module_info.NativeModuleInfo._is_include_need_build')
    @mock.patch('native_module_info.NativeModuleInfo._is_source_need_build')
    @mock.patch.object(logging, 'warning')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_module_need_build_without_needs(
            self, mock_load, mock_warn, mock_src_need, mock_inc_need):
        """Test get_module_includes without needs."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        mock_src_need.return_value = False
        mock_inc_need.return_value = False
        self.assertFalse(mod_info.is_module_need_build('multiarch1'))
        self.assertFalse(mock_warn.called)

    @mock.patch.object(os.path, 'isfile')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_source_need_build_return_true(self, mock_load, mock_isfile):
        """Test _is_source_need_build with source paths or not existing."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        mock_isfile.return_value = False
        self.assertTrue(mod_info._is_source_need_build(
            _CC_NAME_TO_MODULE_INFO['multiarch']))

    @mock.patch.object(os.path, 'isfile')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_source_need_build_return_false(self, mock_load, mock_isfile):
        """Test _is_source_need_build without source paths or paths exist."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        self.assertFalse(mod_info._is_source_need_build(
            _CC_NAME_TO_MODULE_INFO['multiarch1']))
        mock_isfile.return_value = True
        self.assertFalse(mod_info._is_source_need_build(
            _CC_NAME_TO_MODULE_INFO['multiarch']))

    @mock.patch.object(os.path, 'isdir')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_include_need_build_return_true(self, mock_load, mock_isdir):
        """Test _is_include_need_build with include paths and not existing."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mock_isdir.return_value = False
        mod_info = native_module_info.NativeModuleInfo()
        self.assertTrue(mod_info._is_include_need_build(
            _CC_NAME_TO_MODULE_INFO['multiarch']))

    @mock.patch.object(os.path, 'isdir')
    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_is_include_need_build_return_false(self, mock_load, mock_isdir):
        """Test _is_include_need_build without include paths or paths exist."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        self.assertFalse(mod_info._is_include_need_build(
            _CC_NAME_TO_MODULE_INFO['multiarch1']))
        mock_isdir.return_value = True
        self.assertFalse(mod_info._is_include_need_build(
            _CC_NAME_TO_MODULE_INFO['multiarch']))

    def test_not_implemented_methods(self):
        """Test not implemented methods."""
        mod_info = native_module_info.NativeModuleInfo()
        target = 'test'
        with self.assertRaises(NotImplementedError):
            mod_info.get_testable_modules()
        with self.assertRaises(NotImplementedError):
            mod_info.is_testable_module(mock.Mock())
        with self.assertRaises(NotImplementedError):
            mod_info.has_test_config(mock.Mock())
        with self.assertRaises(NotImplementedError):
            mod_info.get_robolectric_test_name(target)
        with self.assertRaises(NotImplementedError):
            mod_info.is_robolectric_test(target)
        with self.assertRaises(NotImplementedError):
            mod_info.is_auto_gen_test_config(target)
        with self.assertRaises(NotImplementedError):
            mod_info.is_robolectric_module(mock.Mock())
        with self.assertRaises(NotImplementedError):
            mod_info.is_native_test(target)

    @mock.patch.object(
        native_module_info.NativeModuleInfo, '_load_module_info_file')
    def test_not_implement_methods_check(self, mock_load):
        """Test for all not implemented methods which should raise error."""
        mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
        mod_info = native_module_info.NativeModuleInfo()
        with self.assertRaises(NotImplementedError):
            suite_name = 'test'
            test_data = {'a': 'test'}
            mod_info.is_suite_in_compatibility_suites(suite_name, test_data)

        with self.assertRaises(NotImplementedError):
            mod_info.get_testable_modules()

        with self.assertRaises(NotImplementedError):
            test_data = {'a': 'test'}
            mod_info.is_testable_module(test_data)

        with self.assertRaises(NotImplementedError):
            test_data = {'a': 'test'}
            mod_info.has_test_config(test_data)

        with self.assertRaises(NotImplementedError):
            test_mod = 'mod_a'
            mod_info.get_robolectric_test_name(test_mod)

        with self.assertRaises(NotImplementedError):
            test_mod = 'mod_a'
            mod_info.is_robolectric_test(test_mod)

        with self.assertRaises(NotImplementedError):
            test_mod = 'a'
            mod_info.is_auto_gen_test_config(test_mod)

        with self.assertRaises(NotImplementedError):
            test_data = {'a': 'test'}
            mod_info.is_robolectric_module(test_data)

        with self.assertRaises(NotImplementedError):
            test_mod = 'a'
            mod_info.is_native_test(test_mod)

    @mock.patch.object(atest.module_info.ModuleInfo, '_load_module_info_file')
    @mock.patch.object(os.path, 'isfile')
    @mock.patch.object(common_util, 'get_json_dict')
    @mock.patch.object(module_info.AidegenModuleInfo,
                       '_discover_mod_file_and_target')
    @mock.patch.object(common_util, 'get_blueprint_json_path')
    def test_load_module_info_file(self, mock_get_json, mock_load, mock_dict,
                                   mock_isfile, mock_base_load):
        """Test _load_module_info_file."""
        force_build = True
        mod_file = '/test/path'
        mock_get_json.return_value = mod_file
        native_module_info.NativeModuleInfo(force_build)
        self.assertTrue(mock_get_json.called_with(
            constant.BLUEPRINT_CC_JSONFILE_NAME))
        mock_load.return_value = mod_file, mod_file
        self.assertTrue(mock_load.called_with(True))
        mock_dict.return_value = _CC_MODULE_INFO
        self.assertTrue(mock_dict.called_with(mod_file))
        self.assertFalse(mock_base_load.called)
        mock_base_load.reset_mock()
        mock_get_json.reset_mock()
        mock_load.reset_mock()
        mock_dict.reset_mock()

        native_module_info.NativeModuleInfo(force_build, mod_file)
        self.assertFalse(mock_get_json.called)
        mock_load.return_value = None, mod_file
        self.assertTrue(mock_load.called_with(True))
        self.assertTrue(mock_dict.called_with(mod_file))
        self.assertFalse(mock_base_load.called)
        mock_base_load.reset_mock()
        mock_get_json.reset_mock()
        mock_load.reset_mock()
        mock_dict.reset_mock()

        force_build = False
        mock_get_json.return_value = mod_file
        native_module_info.NativeModuleInfo(force_build, mod_file)
        self.assertFalse(mock_get_json.called)
        mock_isfile.return_value = True
        self.assertFalse(mock_load.called)
        mock_dict.return_value = _CC_MODULE_INFO
        self.assertTrue(mock_dict.called_with(mod_file))
        self.assertFalse(mock_base_load.called)
        mock_base_load.reset_mock()
        mock_get_json.reset_mock()
        mock_load.reset_mock()
        mock_dict.reset_mock()


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