#!/usr/bin/env python3

# (c) 2019, LeXing Jinag <neeky@live.com 1721900707@qq.com https://www.sqlpy.com/>
# Copyright: (c) 2019, dbm Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

"""
安装 zabbix-agent 
"""

import os
import sys
import psutil
import logging
import argparse
import shutil
from dbma import common
from dbma import checkings
from dbma import errors
from dbma.zabbixdeploy import ZabbixAgentInstaller, ZabbixAgentUninstaller


def parser_cmd_args():
    """
    实现命令行参数的处理
    """
    def empty_to_none(v):
        if v == "":
            return None
        else:
            return v

    name, *_ = os.path.basename(__file__).split('.')
    parser = argparse.ArgumentParser(name)
    parser.add_argument('--pkg', type=str, default="zabbix_agents-4.0.16-linux3.0-amd64-static.tar.gz",
                        help="zabbix-agent install package")
    parser.add_argument('--server-ip', type=str,
                        default="172.16.192.100", help="zabbix server ip")
    parser.add_argument('--agent-ip', type=empty_to_none, default="",
                        help="zabbix agent ip")
    parser.add_argument('--host-name', type=empty_to_none, default="",
                        help="zabbix agent host name")
    parser.add_argument('--net-interface', type=empty_to_none, default='')
    parser.add_argument('--log', type=str, default='info',
                        choices=['debug', 'info', 'warning', 'error'])
    parser.add_argument('action', type=str, choices=[
                        'install', 'uninstall'])
    args = parser.parse_args()
    return args


def config_log(log_file: str, log_level='info'):
    """
    配置日志
    """
    logger = logging.getLogger('dbm-agent')
    if log_level.upper() == 'INFO':
        logger.setLevel(logging.INFO)
    elif log_level.upper() == 'DEBUG':
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.ERROR)

    file_handler = logging.handlers.RotatingFileHandler(
        filename=log_file, maxBytes=1024*1024*20, backupCount=5)
    file_handler.setLevel(logging.DEBUG)

    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(threadName)s - %(levelname)s - %(message)s')

    file_handler.setFormatter(formatter)

    logger.addHandler(file_handler)


def trace_net_interface_ipv4(net_if="ens33"):
    """
    从指定的网卡中提取 ipv4 地址
    """
    # 提取出所有的网卡信息
    addres = psutil.net_if_addrs()

    if net_if not in addres:

        # 如果给定的网卡没有在字典里面就报错
        raise errors.NetInterfaceNotExists(net_if)

    # 如果可以执行到这里，说明给定的网卡是存在的

    net_ip_lst = addres[net_if]
    for ip in net_ip_lst:

        # 如果是 ipv4
        if ip.family == 2:
            return ip.address

    return None


def main():
    """

    """
    args = parser_cmd_args()

    # 配置日志
    level = getattr(logging, args.log.upper())
    logger = logging.getLogger('dbm-agent')
    logger.setLevel(level)
    stream_handler = logging.StreamHandler()
    stream_handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(threadName)s - %(levelname)s - %(lineno)s  - %(message)s')
    stream_handler.setFormatter(formatter)
    logger.addHandler(stream_handler)

    if args.action == 'install':

        # 如果 agent-ip 和 --host-name 都没有指定，那么就直接取网卡地址
        if args.agent_ip is None and args.host_name is None:

            # 提取网卡 IP
            try:
                net_ip = trace_net_interface_ipv4(args.net_interface)
            except errors.Error as err:
                logger.error(str(err))
                sys.exit(1)

            if net_ip is None:

                # 如果提取到的 ip 是 None 应该是没有给定的网卡直接退出
                sys.exit(2)

            #
            args.agent_ip = net_ip
            args.host_name = net_ip

        # 启动安装线程
        zai = ZabbixAgentInstaller(
            server_ip=args.server_ip, agent_ip=args.agent_ip, host_name=args.host_name, pkg=args.pkg)
        zai.start()

        # 等待其执行完成
        zai.join()
    elif args.action == 'uninstall':
        zau = ZabbixAgentUninstaller()
        zau.start()
        zau.join()


if __name__ == "__main__":
    main()
