import os
import paramiko
from django.core.checks import database
from smb.SMBConnection import SMBConnection
from update.models import ClientRelease, Cinema
import pymysql
from pymysql.cursors import DictCursor
from dingxin_toolbox_drf.settings import BASE_DIR
from update.utils.dingxin_sql import *


class ClientUtil:
    def __init__(self):
        self.smb_conn = SMBConnection('admin', 'admin', '', '', use_ntlm_v2=True)
        self.smb_host = '172.16.3.68'
        self.local_path = os.path.join(BASE_DIR, 'dx', 'client')
        self.db_config = {'host': '172.16.3.139', 'port': 3306, 'user': 'clientdeploy',
                          'password': 'clientdeploy123456', 'database': 'yhz_tool'}

    def smb_connect(self):
        self.smb_conn.connect(self.smb_host, 445)

    def smb_disconnect(self):
        self.smb_conn.close()

    def get_all_smb_client(self):
        test_client_list = self.get_smb_file_list('data1', '/客户端/测试专用', r'client_v2.033*.7z')
        prd_client_list = self.get_smb_file_list('data1', '/客户端/结测常用客户端', r'client_v2.033*.7z')
        history_client_list = self.get_smb_file_list('data1', '/客户端/结测常用客户端/历史客户端',
                                                     r'client_v2.033*.7z', )
        return {'test': test_client_list, 'prd': prd_client_list, 'history': history_client_list}

    def get_smb_file_list(self, service_name, path, pattern):
        smb_files = self.smb_conn.listPath(service_name, path, pattern=pattern)
        file_list = []
        for file in smb_files:
            file_name = file.filename
            file_list.append(file_name)
        return file_list

    def handle_client_db(self):
        client_data = self.get_all_smb_client()
        ClientRelease.objects.update(is_delete=True)
        self.write_db(client_data, 'test')
        self.write_db(client_data, 'prd')
        self.write_db(client_data, 'history')

    @staticmethod
    def write_db(_client_data, _type):
        for client in _client_data[_type]:
            file_name = client
            if ClientRelease.objects.filter(origin_name=file_name).first():
                ClientRelease.objects.filter(origin_name=file_name).update(is_delete=False)
            else:
                # 写入数据库
                origin_name = file_name
                main_ver = file_name[8:18]
                sub_ver = file_name[19:23]
                upload_name = file_name[:23] + '.7z'
                client_ver = file_name[8:23]
                ver_id = int(file_name[14:18])
                ClientRelease.objects.create(origin_name=origin_name, main_ver=main_ver, sub_ver=sub_ver,
                                             upload_name=upload_name, client_type=_type, client_ver=client_ver,
                                             ver_id=ver_id)

    def clear_delete_file(self):
        all_delete = ClientRelease.objects.filter(is_delete=True).all()
        for delete in all_delete:
            os.remove(os.path.join(self.local_path, delete.origin_name))

    def get_client_info_from_deploy_db(self, short_ver):
        client_ver = short_ver.replace('0.33', '033')
        db_conn = pymysql.Connect(**self.db_config)
        db_cursor = db_conn.cursor(cursor=DictCursor)
        print(short_ver)
        db_cursor.execute(GET_DEPLOY_CLIENT_INFO, (client_ver,))
        result = db_cursor.fetchone()
        print(result)
        if result is None:
            return None
        return result['full_version']

    @staticmethod
    def get_client_version_from_cine(cinema_ip):
        cine = Cinema.objects.filter(ip=cinema_ip).first()
        db_config = {
            'host': cinema_ip,
            'user': cine.db_user,
            'password': cine.db_pwd,
            'port': 3306,
            'database': 'cine'
        }
        db_conn = pymysql.Connect(**db_config)
        db_cursor = db_conn.cursor(cursor=DictCursor)
        db_cursor.execute('SELECT client_version FROM cinema_version;')
        client_ver = db_cursor.fetchone()['client_version']
        return client_ver

    def download_client_file(self, file_name, path):
        local_file = open(os.path.join(self.local_path, file_name), 'wb')
        # 接收文件并写入本地文件
        self.smb_conn.retrieveFile('data1', rf'{path}{file_name}', local_file)
        # 关闭本地文件
        local_file.close()

    def get_client_version(self, cinema_ip, short_version):
        print('get_client_version')
        print(short_version)
        client_version = self.get_client_info_from_deploy_db(short_version)
        test_client_list = self.get_smb_file_list('data1', '/客户端/测试专用', r'client_v2.033*.7z')
        # 客户端打包服务器上有,smb上没有
        is_exist = False
        for test_client in test_client_list:
            if client_version in test_client:
                is_exist = True
        if is_exist is False:
            client = ClientRelease.objects.filter(ver_id=int(short_version[7:])).order_by('-sub_ver').first()
            client_version = client.client_ver
            print(is_exist)
            print(client_version)
        # 新版本还没有对应的包
        if client_version is None:
            client_version = self.get_client_version_from_cine(cinema_ip)
        print(client_version)
        return client_version

    def get_client(self, cinema_ip, short_version):
        client_version = self.get_client_version(cinema_ip, short_version)
        # 查看本地是否有此版本客户端
        local_file_list = list(os.walk(self.local_path))[0][2]
        for local_file in local_file_list:
            if client_version in local_file:
                print('找到本地文件')
                return
        # 如果本地没有则到服务器上拉取
        client = ClientRelease.objects.filter(client_ver=client_version).first()
        print(client.upload_name)
        if client.client_type == 'test':
            self.download_client_file(client.origin_name, r'/客户端/测试专用/')
        elif client.client_type == 'prd':
            self.download_client_file(client.origin_name, r'/客户端/结测常用客户端/')
        elif client.client_type == 'history':
            self.download_client_file(client.origin_name, r'/客户端/结测常用客户端/历史客户端/')
        else:
            print('检查下载客户端逻辑')

    # 传输客户端的方法
    def upload(self, cine_ip, origin, target):
        # 创建Transport客户端
        trans = paramiko.Transport((cine_ip, 22))
        # 使用密码连接服务器
        trans.connect(username='root', password='cine123456')
        # 创建SFTP客户端
        sftp = paramiko.SFTPClient.from_transport(trans)
        # 上传文件 参数(本地文件路径, 远程文件路径)
        sftp.put(
            os.path.join(self.local_path, origin),
            f"/data0/cine/resource/upload/client/{target}")
        # 关闭客户端
        trans.close()

    def upload_client(self, cinema_ip, short_version):
        # 上传操作
        client_version = self.get_client_version(cinema_ip, short_version)
        client = ClientRelease.objects.filter(client_ver=client_version).first()
        self.upload(cinema_ip, client.origin_name, client.upload_name)
        # 更新数据库
        cine = Cinema.objects.filter(ip=cinema_ip).first()
        db_config = {
            'host': cinema_ip,
            'user': cine.db_user,
            'password': cine.db_pwd,
            'port': 3306,
            'database': 'cine'
        }
        db_conn = pymysql.Connect(**db_config)
        db_cursor = db_conn.cursor(cursor=DictCursor)
        db_cursor.execute('UPDATE cinema_version SET client_version = %s WHERE 1=1;', (client_version,))
        db_conn.commit()
        db_cursor.close()
        db_conn.close()

    def client_process(self, cinema_ip, short_release):
        self.smb_connect()
        short_version = short_release[:11]
        print(short_version)
        self.handle_client_db()
        self.clear_delete_file()
        self.get_client(cinema_ip, short_version)
        self.upload_client(cinema_ip, short_version)
        self.smb_disconnect()

#
# class ClientUtil:
#     def __init__(self):
#         self.smb_conn = SMBConnection('admin', 'admin', '', '', use_ntlm_v2=True)
#         self.smb_host = '172.16.3.68'
#         self.local_path = os.path.join(BASE_DIR, 'dx', 'client')
#
#     def get_test_client_file(self):
#         self.smb_conn.connect(self.smb_host, 445)
#         smb_files = self.smb_conn.listPath('data1', '/客户端/测试专用', pattern=r'client_v2.033*.7z')
#         for file in smb_files:
#             file_name = file.filename
#             print(file_name)
#             if ClientRelease.objects.filter(origin_name=file_name).first():
#                 continue
#             local_file = open(os.path.join(self.local_path, file_name), 'wb')
#             # 接收文件并写入本地文件
#             self.smb_conn.retrieveFile('data1', rf'/客户端/测试专用/{file_name}', local_file)
#             # 关闭本地文件
#             local_file.close()
#             self.write_db(file_name, 'test')
#         self.smb_conn.close()
#         # return smb_files
#
#     def get_prd_client_file(self):
#         self.smb_conn.connect(self.smb_host, 445)
#         prd_smb_files = self.smb_conn.listPath('data1', '/客户端/结测常用客户端', pattern=r'client_v2.033*.7z')
#         for file in prd_smb_files:
#             file_name = file.filename
#             print(file_name)
#             if ClientRelease.objects.filter(origin_name=file_name).first():
#                 continue
#             local_file = open(os.path.join(self.local_path, file_name), 'wb')
#             # 接收文件并写入本地文件
#             self.smb_conn.retrieveFile('data1', rf'/客户端/结测常用客户端/{file_name}', local_file)
#             # 关闭本地文件
#             local_file.close()
#             self.write_db(file_name, 'prd')
#
#         history_smb_files = self.smb_conn.listPath('data1', '/客户端/结测常用客户端/历史客户端',
#                                                    pattern=r'client_v2.033*.7z')
#         for file in history_smb_files:
#             file_name = file.filename
#             print(file_name)
#             if ClientRelease.objects.filter(origin_name=file_name).first():
#                 continue
#             local_file = open(os.path.join(self.local_path, file_name), 'wb')
#             # 接收文件并写入本地文件
#             self.smb_conn.retrieveFile('data1', rf'/客户端/结测常用客户端/历史客户端/{file_name}', local_file)
#             # 关闭本地文件
#             local_file.close()
#             self.write_db(file_name, 'prd')
#         self.smb_conn.close()
#
#     @staticmethod
#     def write_db(_file, _type):
#         # 写入数据库
#         origin_name = _file
#         main_ver = _file[8:18]
#         sub_ver = _file[19:23]
#         upload_name = _file[:23] + '.7z'
#         client_ver = _file[8:23]
#         ver_id = int(_file[14:18])
#         ClientRelease.objects.create(origin_name=origin_name, main_ver=main_ver, sub_ver=sub_ver,
#                                      upload_name=upload_name, client_type=_type, client_ver=client_ver, ver_id=ver_id)
#
#     def update_client_file(self):
#         prd_clients = self.get_prd_client_file()
#         test_clients = self.get_test_client_file()
#         all_clients = prd_clients + test_clients
#         all_db_clients = ClientRelease.objects.filter(is_delete='0').all()
#         for db_client in all_db_clients:
#             if db_client['origin_name'] in all_clients:
#                 continue
#             else:
#                 ClientRelease.objects.filter(pk=db_client['id']).update(is_delete='1')
#                 path = f'../../dx/client/{db_client["origin_name"]}'
#                 os.remove(path)
#
#     def upload_client_file(self, cinema_ip, _release):
#         cine = Cinema.objects.filter(ip=cinema_ip).first()
#         db_config = {
#             'host': cinema_ip,
#             'username': cine['db_user'],
#             'password': cine['db_pwd'],
#             'port': 3306,
#             'database': 'cine'
#         }
#         db_conn = pymysql.Connect(**db_config)
#         db_cursor = db_conn.cursor(cursor=DictCursor)
#         # 获取客户端信息
#         client = ClientRelease.objects.filter(main_ver=_release).order_by('-sub_ver').first()
#         print(client)
#         if client:
#             self.upload(cinema_ip, client['origin_name'], client['upload_name'])
#             db_cursor.execute('UPDATE cinema_version SET client_version = %s WHERE 1=1;', (client['client_ver'],))
#         else:
#             db_cursor.execute('SELECT client_version FROM cinema_version;')
#             client_ver = db_cursor.fetchone()['client_version']
#             client = ClientRelease.objects.filter(client_ver=client_ver).order_by('-sub_ver').first()
#             self.upload(cinema_ip, client['origin_name'], client['upload_name'])
#
#     @staticmethod
#     def upload(cine_ip, origin, target):
#         # 创建Transport客户端
#         trans = paramiko.Transport((cine_ip, 22))
#         # 使用密码连接服务器
#         trans.connect(username='root', password='cine123456')
#         # 创建SFTP客户端
#         sftp = paramiko.SFTPClient.from_transport(trans)
#         # 上传文件 参数(本地文件路径, 远程文件路径)
#         sftp.put(
#             f"../../dx/client/{origin}",
#             f"/data0/cine/resource/upload/client/{target}")
#         # 关闭客户端
#         trans.close()