# -*- coding:utf-8 -*-
import os
import shutil
import time

from huansi_utils.app.apploader import logger
from huansi_utils.db.db import new_id
from huansi_utils.exception.exception import HSException
from huansi_utils.server.service_uc import HSBaseUCService
import docker

from app.conncetion.conncetion_service import ConnectionService
from app.utils.db_tools import db_driver
from static_file import builds_dir, back_up_dir

# docker_client = docker.APIClient(base_url='tcp://localhost:2375')
docker_client = docker.APIClient(base_url='unix:///var/run/docker.sock')


class InfoService(HSBaseUCService):

    def get_app_list(self):
        project_info = ConnectionService().get_project_info()
        if not project_info:
            raise HSException('请先设置项目信息')

        host_ip = project_info.get('host_ip')
        # host_ip = 'localhost'
        containers = docker_client.containers()
        app_info_list = []
        for container in containers:
            app_info = {}
            app_info['app_name'] = container['Names'][0][1:]  # "/***"这种格式

            # logger.info('容器{}信息:{}'.format(app_info['app_name'], container))
            port_list = container['Ports']
            if port_list:
                app_url_list = [f"{host_ip}:{port.get('PublicPort')}" for port in port_list if port.get('PublicPort')]
                app_info['app_url'] = '  '.join(app_url_list)
            else:
                app_info['app_url'] = ''
            image_name = container['Image']
            # 区分版本号
            if ':' in image_name:
                verison = image_name.split(':')[-1:][0]
            else:
                verison = 'latest'
            app_info['version'] = verison
            app_info['state'] = container['State']
            app_info['status'] = container['Status']
            app_info['creat_time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(container['Created']))
            app_info_list.append(app_info)

        return app_info_list

    def set_upgrade_info(self, app_list):
        '''
        设置app升级信息
        :arg app_list [{app_code,app_name,app_image}]
        :return:
        '''
        logger.info(f'获取到的升级app列表:{app_list}')

        log_id = new_id()
        sql_list = []

        if not app_list:
            raise HSException('app信息为空')

        import time
        upgrade_no = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))

        # 新增表头
        sql = f'''insert into app_upgrade_log
(id,status,default_version,upgrade_no)
values 
({log_id},'成功',1,'{upgrade_no}')'''

        sql_list.append(sql)

        # 更新之前的升级app状态
        sql = f'''update app_upgrade_log
set default_version=0
where id <> {log_id}'''

        sql_list.append(sql)

        for app in app_list:
            app_image = app.get('app_image', '')
            app_code = app.get('app_code', '')
            app_name = app.get('app_name', '')
            app_image_info = docker_client.images(name=app_image)
            if not app_image_info:
                raise HSException(f'找不到[{app_image}]的具体镜像')
            app_image_id = app_image_info[0]['Id'].replace('sha256:', '')
            app_image_name = app_image_info[0]['RepoTags'][0]
            _sql = f'''insert into app_upgrade_log_dtl
(log_id,app_code,app_name,app_image_id,app_image_name)
values
({log_id},'{app_code}','{app_name}','{app_image_id}','{app_image_name}')'''

            sql_list.append(_sql)

        with db_driver as session:
            for sql_str in sql_list:
                session.exec_sql(sql_str)

            # 备份升级文件
            # 映射数据卷的时候,back_up_dir文件会丢失,重新创建一下
            if not os.path.exists(back_up_dir):
                os.mkdir(back_up_dir)

            upgrade_back_up_dir = os.path.join(back_up_dir, upgrade_no)
            if not os.path.exists(upgrade_back_up_dir):
                os.mkdir(upgrade_back_up_dir)

            deploy_dir = os.path.join(builds_dir, 'deploy')

            for files in os.listdir(deploy_dir):
                name = os.path.join(deploy_dir, files)
                back_name = os.path.join(upgrade_back_up_dir, files)
                # 有一个文件夹.git
                if os.path.isfile(name):
                    shutil.copy(name, back_name)

        return {'message': '写入成功'}

    def get_upgrade_log(self):
        '''
        获取升级历史信息
        :return:
        '''
        sql = '''select A.*,(select count(*) from app_upgrade_log_dtl where log_id=A.id) as count
from app_upgrade_log A
order by A.default_version desc, A.upgrade_time desc
'''
        with db_driver as session:
            data = session.query_sql(sql)

        return data

    def get_upgrade_log_dtl(self, log_id):
        '''
        获取升级历史信息详情
        :param log_id:
        :return:
        '''
        sql = f'''select A.*
from app_upgrade_log_dtl A
where A.log_id={log_id}
'''
        with db_driver as session:
            data = session.query_sql(sql)

        return data