#!/usr/bin/python3
# -*- coding: utf-8 -*-
import binascii
import gettext
import base64
import json
import os
import subprocess
from time import sleep
import dbus
import argparse
import logging
import socket
import errno

from pydbus import SystemBus

default_server = None  # 加域的服务器地址
default_username = None  # 加域账户名
default_password = None  # 加域账户密码
default_client_name = None  # 客户端主机名

# default_server = 'server.example.local'  # 加域的服务器地址
# default_username = 'domain-account'  # 加域账户名
# default_password = 'a3lsaW4xMjMuCg=='  # 加域账户密码
# default_client_name = 'client.example.local'  # 客户端主机名

# -------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------

default_password_encryption = False  # 当该值为True时,脚本会对账户密码进行解码操作
default_is_reboot_machine = False  # 当该值为True时,仅当加域成功后,重启机器


logger = logging.getLogger()
gettext.bindtextdomain('kim-domain', '/usr/share/kim-client/locale')
gettext.textdomain('kim-domain')
_ = gettext.gettext

# -------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------

JOIN_ERR_UNKNOW = 100101                #未知错误
JOIN_ERR_NOTJOIN = 100102               #未加域
JOIN_ERR_CONFIG = 100103                #配置错误
JOIN_ERR_TIME_SKEW = 100104             #客户端与服务端时间相差过大
JOIN_ERR_RUN_NOPERM = 100105            #脚本需要root权限
JOIN_ERR_CLIENT_ERR = 100106            #客户端未安装或服务异常
JOIN_ERR_PARAM_ERR = 100107             #脚本参数错误
JOIN_ERR_ALREADY_JOIN = 100108          #已加域
JOIN_ERR_BACKEND = 100109               #后端错误

JOIN_ERR_NET_URL = 100201               #访问地址异常
JOIN_ERR_NET_TIMEOUT = 100202           #连接服务端超时
JOIN_ERR_NET_CONN = 100203              #连接网络异常
JOIN_ERR_NET_REQUEST = 100204           #请求错误
JOIN_ERR_NET_STATUS = 100205            #http请求状态码异常

JOIN_ERR_KCM = 100301                   #KCM调用错误

def out_put_err(err_code, err_msg):
    #with open('installmsg', 'w') as f:
    #    f.write('errcode = %d\n' % err_code)
    #    f.write('errmsg = %s\n' % err_msg)
    print('[%d]%s' % (err_code, err_msg))
    if err_code != 0 and err_code != 300000:
        exit(1)
    else:
        exit(0)

def out_msg(type, code, msg):
    if type == 'json':
        pass
    if type == 'line':
        print('[%d]%s' % (code, msg))
    if type == '':
        pass

def domain_status():
    dbus_object = SystemBus()
    service = dbus_object.get("com.kylin.kim.domain", "/")
    interface = service["com.kylin.kim.domain"]
    status = interface.getDomainStatus()
    return status

def domain_join(args):
    server = args.server
    username = args.username
    password = args.password
    password_encryption = args.password_encryption
    is_reboot_machine = args.is_reboot_machine

    status = domain_status()
    if status != 0:
        return JOIN_ERR_ALREADY_JOIN, '终端已加域'

    client_name = args.client_name
    if client_name is None:
        client_name = socket.getfqdn()
    try:
        dbus_object = SystemBus()
        service = dbus_object.get("com.kylin.kim.domain", "/")
        interface = service["com.kylin.kim.domain"]
    except dbus.exceptions.DBusException as error_message:
        return JOIN_ERR_CLIENT_ERR, '加域状态 : 请检查加域客户端软件包是否安装或其版本是否正确 (%s)' % error_message
    if password_encryption:
        try:
            password = str(base64.b64decode(
                password).decode()).replace('\n', '')
        except Exception as error_message:
            return JOIN_ERR_PARAM_ERR, ('加域状态 : 加域账号密码 解码错误，请检查密码是否正确 (%s)' % error_message)

    status, msg = interface.userJoinCommand(
        server, client_name, username, password)

    if status == 0:
        return 0, '加域状态 : 成功'
    else:
        return JOIN_ERR_BACKEND, "失败 (%s)" % msg


def domain_uninstall(args):
    server = args.server
    username = args.username
    password = args.password
    password_encryption = args.password_encryption

    if domain_status() == 0:
        return JOIN_ERR_NOTJOIN, '终端未加域'

    try:
        if password_encryption:
            password = str(base64.b64decode(
                password).decode()).replace('\n', '')

        dbus_object = SystemBus()
        service = dbus_object.get("com.kylin.kim.domain", "/")
        interface = service["com.kylin.kim.domain"]
        ret, msg = interface.userAuthRemote(username, password)
        if ret != 0:
            return errno.EACCES, "退域认证失败：%s" % msg
        ret, msg = interface.unenroll()
        #out_put_err(ret, msg)
        if ret != 0:
            return errno.EACCES, ("退域状态 : %s" % msg)
    except binascii.Error as error_message:
        return errno.EINVAL, ("退域状态 : 失败 (账号密码 解码错误，请检查密码是否正确 - %s)" % str(error_message))
    except Exception as error_message:
        return errno.EINVAL, ("退域状态 : 失败 (%s)" % str(error_message))

    return 0, ("退域状态 : 成功")

# -------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------


# 创建 ArgumentParser 对象
parser = argparse.ArgumentParser(
    description='Join domain Using the Command Line')

# 创建子命令解释器
subparsers = parser.add_subparsers(dest="command")  # dest: 子命令名称在命名空间中使用的键
sub_status = subparsers.add_parser('status')
# 添加子命令 'install'
sub_install = subparsers.add_parser('install')
# 添加子命令 'uninstall'
sub_uninstall = subparsers.add_parser('uninstall')
# 为 'install' 子命令创建参数组
group_install = sub_install.add_argument_group()
# 在参数组中添加参数
group_install.add_argument('--server', default=default_server, required=not default_server,
                           help='Server Domain Name/Address')
group_install.add_argument('--username', default=default_username, required=not default_username,
                           help='Add domain account')
group_install.add_argument('--password', default=default_password, required=not default_password,
                           help='Add domain account password')
group_install.add_argument('--client-name', default=default_client_name, required=False,
                           help='Client host name')

group_install.add_argument('--password-encryption', action='store_true', default=default_password_encryption,
                           help='Whether the password of the domain account is encrypted')
group_install.add_argument('--is-reboot-machine', action='store_true', default=default_is_reboot_machine,
                           help='Whether to restart the machine after the domain is successfully added')

# 为 'uninstall' 子命令创建参数组
group_uninstall = sub_uninstall.add_argument_group()

group_uninstall.add_argument('--server', required=False,
                             help='Server Domain Name/Address')
group_uninstall.add_argument('--username', default=default_username, required=not default_username,
                             help='Add domain account')
group_uninstall.add_argument('--password', default=default_password, required=not default_password,
                             help='Add domain account password')
group_uninstall.add_argument('--password-encryption', action='store_true',
                             help='Whether the password of the domain account is encrypted')
group_uninstall.add_argument('--is-reboot-machine', action='store_true', default=default_is_reboot_machine,
                             help='Whether to restart the machine after the domain is successfully unenrolled')


# 解析命令行参数
args = parser.parse_args()



if args.command == 'install':
    # 处理 'install' 子命令逻辑
    if os.geteuid() != 0:
        print("请使用管理员权限执行")
        out_put_err(JOIN_ERR_RUN_NOPERM, "请使用管理员权限执行")
        exit()
    is_reboot_machine = args.is_reboot_machine
    ret, msg = domain_join(args)

    print(msg)

    if ret == 0 and is_reboot_machine:
        try:
            print(
                "\033[033m系统将在十秒后重启, 按\033[031mCtrl + C\033[0m \033[033m取消.\033[0m")
            sleep(10)
            os.system("reboot")
        except KeyboardInterrupt:
            exit()
    exit(ret)

elif args.command == 'uninstall':
    # 处理 'uninstall' 子命令逻辑
    if os.geteuid() != 0:
        print("请使用管理员权限执行")
        out_put_err(JOIN_ERR_RUN_NOPERM, "请使用管理员权限执行")
        exit()
    is_reboot_machine = args.is_reboot_machine
    ret, msg = domain_uninstall(args)
    print(msg)
    if ret == 0 and is_reboot_machine:
        try:
            print(
                "\033[033m系统将在十秒后重启, 按\033[031mCtrl + C\033[0m \033[033m取消.\033[0m")
            sleep(10)
            os.system("reboot")
        except KeyboardInterrupt:
            exit()
    exit(ret)

elif args.command == 'status':
    try:
        status = domain_status()
        print(status)
        exit()
    except Exception as error_message:
        print("获取域状态 : 失败 (%s)" % str(error_message))
        exit(1)

else:
    # 如果没有指定子命令，则退出
    parser.print_help()
    #out_put_err(JOIN_ERR_PARAM_ERR, '参数错误')
    exit(-1)
