import os
import shutil
from quart import jsonify, request,session,flash,redirect
from . import api
from web.common.utils import login_required
from core.DBManager import mDBM
from core.ModelManager import mMM
from core.Upload_file import allowed_file,check_file
from myutils.ConfigManager import myCongif
from werkzeug.utils import secure_filename

@api.route('/model/list',methods=['GET'])
@login_required
async def model_list(): #获取算法列表
    strsql = "select ID,model_name,version,duration_time,proportion from model;"
    datas = mDBM.do_select(strsql)
    reMsg = [{"ID":data[0],"name":data[1],"version":data[2],"duration_time":data[3],
              "proportion":data[4]} for data in datas]
    return jsonify(reMsg)

def restart_work(mid):
    strsql = f"select channel_id from channel2model where model_id = {mid};"
    datas = mDBM.do_select(strsql)
    if datas:  # 有关联
        print("有关联")
        # 重启通道业务
        for data in datas:
            mMM.restartC2M(data[0])  # 根该模型关联的所有通道都需要重启工作线程

@api.route('/model/add',methods=['POST'])
@login_required
async def model_add(): #新增算法
    reStatus = 0
    reMsg = "有错误!"
    form = await request.form
    model_name = form['mName']
    files = await request.files
    if 'file' not in files:
        reMsg = '参数错误'
        return jsonify({'status': reStatus, 'msg': reMsg})
    file = files['file']
    if file.filename == '':
        reMsg =  '没有选择文件'
        return jsonify({'status': reStatus, 'msg': reMsg})
    #判断算法名称是否重复
    strsql = f"select ID from model where model_name='{model_name}';"
    data = mDBM.do_select(strsql, 1)
    if data:
        reMsg = "算法名称重复,请修改!"
    else:
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)   #安全过滤
            file_path = os.path.join(myCongif.get_data('UPLOAD_FOLDER'), filename)
            await file.save(file_path)
            #检查上传文件的合法性,若符合要求移动到正式路径
            filename_pre = filename.rsplit('.',1)[0] #除去到.zip
            model_version, model_name_file, model_path = check_file(file_path,filename_pre,2) #itype--2 是算法模型升级  1-系统升级
            #删除压缩包
            os.remove(file_path)
            if model_version and model_path:
                #model表插入数据
                strsql = (f"insert into model (model_name,version,model_path) values "
                          f"('{model_name}','{model_version}','{model_path}');")
                ret = mDBM.do_sql(strsql)
                if ret:
                    reStatus = 1
                    reMsg = '算法添加成功'
                else:
                    reMsg = '插入数据库出错,请联系技术支持!!'
            else:
                reMsg = '升级包不合法,请重新上传!'
        else:
            reMsg = '只允许上传zip文件'
    #新增算法,不需要处理通道关联的相关业务
    return jsonify({'status': reStatus, 'msg': reMsg})

@api.route('/model/upgrade',methods=['POST'])
@login_required
async def model_upgrade(): #升级算法,需要先上传算法文件
    reStatus = 0
    reMsg = "有错误!"
    form = await request.form
    mid = form['mid']
    files = await request.files
    if 'file' not in files:
        reMsg = '参数错误'
        return jsonify({'status': reStatus, 'msg': reMsg})
    file = files['file']
    if file.filename == '':
        reMsg = '没有选择文件'
        return jsonify({'status': reStatus, 'msg': reMsg})
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)  # 安全过滤
        file_path = os.path.join(myCongif.get_data('UPLOAD_FOLDER'), filename)
        await file.save(file_path)
        # 检查上传文件的合法性,若符合要求移动到正式路径
        filename_pre = filename.rsplit('.', 1)[0]  # 除去到.zip
        model_version, model_name_file, model_path = check_file(file_path, filename_pre, 2)  # itype--2 是算法模型升级  1-系统升级
        # 删除压缩包
        os.remove(file_path)
        if model_version and model_path:
            strsql = (f"update model set version='{model_version}',model_path='{model_path}' "
                      f"where ID={mid};")
            ret = mDBM.do_sql(strsql)
            if ret:
                reStatus = 1
                reMsg = '升級算法成功'
                #重启业务数据
                restart_work(mid)
            else:
                reMsg = '修改数据库出错,请联系技术支持!!'
        else:
            reMsg = '升级包不合法,请重新上传!'
    else:
        reMsg = '只允许上传zip文件'

    return jsonify({'status': reStatus, 'msg': reMsg})

@api.route('/model/del',methods=['POST'])
@login_required
async def model_del():
    json_data = await request.get_json()
    mid = json_data.get('mid')
    #删除与该算法关联的通道相关数据
    strsql = f"select channel_id from channel2model where model_id = {mid};"
    datas = mDBM.do_select(strsql)
    if datas:   #有关联
        #删与通道的关联信息 --c2m,schedule
        mDBM.delC2M(mid,2)
        #重启通道业务
        for data in datas:
            mMM.restartC2M(data[0]) #根该模型关联的所有通道都需要重启工作线程

    #删除算法文件
    strsql = f"select model_path from model where ID = {mid};"
    data = mDBM.do_select(strsql,1)
    if data:
        py_path = data[0]
        dir_path = py_path.rsplit('/',1)[0] #正常最后一层应该都是/--手动加的
        print(dir_path)
        shutil.rmtree(dir_path)
    # 删该算法记录
    strsql = f"delete from model where ID = {mid};"
    mDBM.do_sql(strsql)
    #正常来说删除一般不会失败
    return jsonify({'status': 1, 'msg': "删除成功"})

@api.route('/model/changecnf',methods=['POST'])
@login_required
async def model_config_change(): #修改算法的配置信息
    json_data = await request.get_json()
    mid = json_data.get('mid')
    reStatus = 0
    try:
        duration_time = int(json_data.get('duration_time'))
        proportion = float(json_data.get('proportion'))
        if proportion > 0 and proportion < 1:
            strsql = f"update model set duration_time='{duration_time}',proportion='{proportion}' where ID={mid};"
            ret = mDBM.do_sql(strsql)
            if ret:
                reStatus = 1
                reMsg = "修改算法配置成功"
                #重启-工作线程
                restart_work(mid)
            else:
                reMsg = "修改算法配置失败"
        else:
            reMsg = "占比阈值需要为大于0,小于1的值"
    except ValueError:
        reMsg = "数据类型不对!"
    return jsonify({'status': reStatus, 'msg': reMsg})