#!/usr/bin/env python3
# coding: utf-8
# Copyright 2024 Huawei Technologies Co., Ltd
#
# 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.
# ===========================================================================
"""
install_python.py 系统测试
测试 ascend_deployer/library/install_python.py 模块。
"""

import abc
import os
import sys
import types
from unittest.mock import patch, MagicMock, Mock

# 添加项目根目录到路径,以便导入 library_test
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))
test_dir = os.path.join(project_root, 'test')

# 使用动态方式添加路径
path_method = getattr(sys, 'path')
insert_method = getattr(path_method, 'insert')

# 确保路径唯一性,避免重复添加
if project_root not in path_method:
    insert_method(0, project_root)
if test_dir not in path_method:
    insert_method(0, test_dir)

from library_test.base_test import BaseLibraryTest
from library_test.mock_manage.mock_model.mock_ansible_module import AnsibleModule
from library_test.mock_manage.mock_handlers.mock_cmd_handler import MockCmdHandler

ANSIBLE_FIELD = "ansible"
MODULE_UTILS_FIELD = f"{ANSIBLE_FIELD}.module_utils"
BASIC_FIELD = f"{MODULE_UTILS_FIELD}.basic"


class TestBasePythonInstaller(BaseLibraryTest, metaclass=abc.ABCMeta):
    TESTCASE_DIR = os.path.join(os.path.dirname(__file__), "testcase")

    @classmethod
    def get_module_path(cls):
        return "ascend_deployer.library.install_python"

    @classmethod
    def get_testcase_path(cls):
        return os.path.join(cls.TESTCASE_DIR, "python.yml")

    @classmethod
    def setUpClass(cls):
        # 先调用父类的setUp
        super().setUpClass()
        
        # 确保 ansible 模块结构被正确模拟
        if ANSIBLE_FIELD in sys.modules:
            del sys.modules[ANSIBLE_FIELD]
        if MODULE_UTILS_FIELD in sys.modules:
            del sys.modules[MODULE_UTILS_FIELD]
        if BASIC_FIELD in sys.modules:
            del sys.modules[BASIC_FIELD]
        
        # 模拟 ansible.module_utils.basic 模块
        sys.modules[ANSIBLE_FIELD] = types.ModuleType(ANSIBLE_FIELD)
        sys.modules[MODULE_UTILS_FIELD] = types.ModuleType(MODULE_UTILS_FIELD)
        sys.modules[BASIC_FIELD] = types.ModuleType(BASIC_FIELD)

        # 创建一个模拟的 AnsibleModule 类
        def mock_ansible_module(argument_spec=None, **kwargs):
            mock_module = Mock()
            mock_module.params = {}
            mock_module.fail_json = Mock(side_effect=Exception("Failed"))
            mock_module.exit_json = Mock()
            return mock_module

        # 将模拟的 AnsibleModule 赋值给模块
        sys.modules[BASIC_FIELD].AnsibleModule = mock_ansible_module
        
        # 现在导入 PythonInstaller
        from ascend_deployer.library.install_python import PythonInstaller
        cls.PythonInstaller = PythonInstaller


class TestPythonInstaller(TestBasePythonInstaller):
    """测试 PythonInstaller 类"""
    
    def test_create_ascendrc(self):
        """测试创建 ascendrc 文件"""
        params = {
            "resources_dir": "/tmp/test_resources",
            "python_tar": "Python-3.9.0",
            "os_and_arch": "CentOS_7.6_aarch64"
        }
        
        mock_module = self._create_mock_ansible_module(params)
        
        with patch('subprocess.Popen') as mock_popen:
            mock_result = MagicMock()
            mock_result.returncode = 0
            mock_result.communicate.return_value = ("", "")
            mock_popen.return_value = mock_result
            
            installer = self.PythonInstaller()
            installer.module = mock_module
                
            # Mock local_path 为临时目录
            test_local_path = "/tmp/test_local"
            os.makedirs(test_local_path, exist_ok=True)
            installer.local_path = test_local_path
                
            installer.create_ascendrc()
                
            # 验证 ascendrc 文件被创建
            ascendrc_path = "{}/ascendrc".format(installer.local_path)
            self.assertTrue(os.path.exists(ascendrc_path))
                
            # 读取文件内容验证
            with open(ascendrc_path, 'r') as f:
                content = f.read()
                
            # 验证内容包含正确的环境变量
            self.assertIn("export PATH=/tmp/test_local/python3.9.0/bin:$PATH", content)
            self.assertIn("export LD_LIBRARY_PATH=/tmp/test_local/python3.9.0/lib:$LD_LIBRARY_PATH", content)

    def _create_mock_ansible_module(self, params):
        """创建模拟的 AnsibleModule 实例"""
        cmd_handler = MockCmdHandler([], {})
        return AnsibleModule(params, cmd_handler)


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