# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import pathlib
import utils.common.log as logger
from utils.common.ssh_util import Ssh
from utils.common.fic_base import TestCase
from plugins.DistributedStorage.logic.vm_operate import VMOperate
from plugins.DistributedStorage.logic.install_operate import InstallOperate
from plugins.DistributedStorage.utils.iterm.parameter_gain import ParamsGain
from plugins.DistributedStorage.utils.common.deploy_constant import DeployConstant


class UploadHotPatchImpl(TestCase):
    def __init__(self, project_id, pod_id, fs_args):
        super(UploadHotPatchImpl, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.fs_args = fs_args
        self.hot_patch_reg = DeployConstant.HOT_PATCH_PATTERN
        self.dst_dir = "/opt/fusionstorage/repository/deploymanager_patch_pkg"
        self.fsadmin_dir = "/home/fsadmin"
        self.vm_operate = VMOperate(self.project_id, self.pod_id, fs_args)

    @classmethod
    def creat_root_client(cls, node_info):
        client = InstallOperate.create_ssh_root_client(
            node_info.get('om_ip'),
            node_info.get("user"),
            node_info.get("passwd"),
            node_info.get("root_pwd")
        )
        return client

    def _create_dir(self, node_info: dict):
        client = self.creat_root_client(node_info)
        cmd_items = ['test -d {0} && rm -rf {0}/'.format(self.dst_dir),
                     'mkdir -p {}'.format(self.dst_dir),
                     'chmod 700 -R {}'.format(self.dst_dir),
                     'touch {}/install'.format(self.dst_dir),
                     'chmod 600 {}/install'.format(self.dst_dir)]
        try:
            cmd_res = Ssh.ssh_send_command(client, ";".join(cmd_items), "#", 20, 3)
        finally:
            Ssh.ssh_close(client)
        logger.info("Make an directory on host:{}, result: {}".format(node_info.get('om_ip'), cmd_res))

    def _upload_hot_patch_pkg(self, node_info: dict, src_path: str):
        logger.info("Start to upload package {} to host {}".format(src_path, node_info.get('om_ip')))
        Ssh.put_file(
            node_info.get('om_ip'),
            node_info.get("user"),
            node_info.get("passwd"),
            src_path,
            destination=self.fsadmin_dir
        )
        logger.info("Upload package complete, host:{}".format(node_info.get('om_ip')))

    def _move_pkg_to_dst_dir(self, node_info: dict, pkg_name):
        client = self.creat_root_client(node_info)
        cmd = "mv {0}/{2} {1};chmod 700 {1}/{2}".format(self.fsadmin_dir, self.dst_dir, pkg_name)
        try:
            cmd_res = Ssh.ssh_send_command(client, cmd, "#", 20, 3)
        finally:
            Ssh.ssh_close(client)
        logger.info("host:{}, cmd:{}, result: {}".format(node_info.get('om_ip'), cmd, cmd_res))

    def procedure(self):
        logger.info("start to upload patch package")
        pkg_path, pkg_name = ParamsGain.get_package(self.hot_patch_reg)
        logger.info("package path:{}, package name:{}".format(pkg_path, pkg_name))
        if not pkg_name:
            err_msg = "The hot patch package {} does not exist " \
                      "in the {} directory.".format(self.hot_patch_reg, pkg_path)
            logger.error(err_msg)
            raise Exception(err_msg)

        logger.info("Query node Authentication information")
        nodes_info = self.vm_operate.get_vm_data(self.pod_id, self.fs_args.get("float_ip"))

        for node_info in nodes_info:
            logger.info("upload patch, host:{}".format(node_info.get("om_ip")))
            self._create_dir(node_info)
            self._upload_hot_patch_pkg(node_info, str(pathlib.Path(pkg_path) / pkg_name))
            self._move_pkg_to_dst_dir(node_info, pkg_name)
            logger.info("Upload completed. host:{}".format(node_info.get("om_ip")))

        logger.info("finish")
