from flask import Flask, request
from flask.json import jsonify
from data.para_config import *
from equipment.truck import TruckInfo
from equipment.excavator import ExcavatorInfo
from equipment.dump import DumpInfo
from core.dispatcher import PreSchedule
from core.group import Group
from flask_caching import Cache
from alg.algorithm import ExpectedTime
from data.dispatchInfo import DispatchInfo
from core.submit import DispatchSubmission
from core.group import GroupDispatcher
from core.group import group_direct2redis

config = {
    "DEBUG": True,          # some Flask specific configs
    "CACHE_TYPE": "SimpleCache",  # Flask-Caching related configs
    "CACHE_DEFAULT_TIMEOUT": 300
}

app = Flask(__name__)
app.config.from_mapping(config)
cache = Cache(app)


@app.route("/dispatch", methods=["POST"])
def dispatch_request():

    # 获取报文数据
    data_json = request.get_json()

    # 分组id
    group_id = data_json.get("group_id")

    # 调度开始时间
    rtd_start_time = datetime.now()

    # 初始化日志
    set_log()
    # 获取日志器
    logger = get_logger("zxt.request")

    # 更新周期参数
    logger.info("#####################################请求调度更新开始#####################################")

    try:

        # 清空数据库缓存
        session_mysql.commit()
        session_mysql.flush()

        # 清空数据库缓存
        session_postgre.commit()
        session_postgre.flush()
    except Exception as es:
        logger.error("数据库访问异常")
        logger.error(es)
        return jsonify(msg="未知异常, 请联系管理员", code=501)

    try:

        # 全局参数更新
        global_period_para_update()
        # get_global_para_from_cache(cache)

    except Exception as es:
        logger.error("全局参数更新异常")
        logger.error(es)
        session_mysql.rollback()
        session_postgre.rollback()
        return jsonify(msg="未知异常, 请联系管理员", code=502)

    try:
        # 更新调度信息
        DispatchInfo.reset()

        DispatchInfo.update_device_group_structure()

        if group_id not in DispatchInfo.group_set:
            raise Exception("请求调度分组不存在")

        DispatchInfo.update_route_distance()

        DispatchInfo.update_group_mode()

        DispatchInfo.update_group_name()
    except Exception as es:
        logger.error("调度信息更新异常")
        logger.error(es)
        session_mysql.rollback()
        session_postgre.rollback()
        return jsonify(msg="未知异常, 请联系管理员", code=503)

    logger.info("Dispatchinfo，更新后信息")
    logger.info("group_set")
    logger.info(DispatchInfo.group_set)
    logger.info("group_excavator_dict")
    logger.info(DispatchInfo.group_excavator_dict)
    logger.info("group_unload_area_dict")
    logger.info(DispatchInfo.group_unload_area_dict)
    logger.info("group_truck_dict")
    logger.info(DispatchInfo.group_truck_dict)
    logger.info("group_mode")
    logger.info(DispatchInfo.group_mode)
    logger.info("load_distance")
    logger.info(DispatchInfo.load_distance)
    logger.info("unload_distance")
    logger.info(DispatchInfo.unload_distance)

    try:

        # 实例化设备对象
        dump = DumpInfo()
        excavator = ExcavatorInfo()
        truck = TruckInfo(dump, excavator)

        # 设备信息更新
        dump.dump_para_period_update()
        excavator.excavator_para_period_update()
        truck.truck_para_period_update(dump, excavator)
        truck.state_period_update()

        # 实例化调度预测器
        pre_sch = PreSchedule(truck, excavator, dump)

        # 实例化输出器
        submission = DispatchSubmission(dump, excavator, truck)

        # 实例化调度分组
        group = Group(group_id, truck, pre_sch, excavator, dump)

        # 更新调度分组信息
        group.info_update()

    except Exception as es:
        logger.error("对象实例化异常")
        logger.error(es)
        session_mysql.rollback()
        session_postgre.rollback()
        return jsonify(msg="未知异常, 请联系管理员", code=504)

    try:

        # # 调度分组派车计划计算
        # try:
        #     truck_dispatch_plan_dict = group.group_dispatch(ExpectedTime)
        # except Exception as es:
        #     logger.error(es)
        #     logger.error(f'分组{group.group_id} 调度计算异常')
        #
        # try:
        #
        #     logger.info(f'调度分组: {group.group_id} {DispatchInfo.group_name[group.group_id]}')
        #     submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict)
        # except Exception as es:
        #     logger.error(es)
        #     logger.error(f'分组{group.group_id} 调度写入异常')

        # 调度分组派车计划计算
        try:
            group_dispatcher = GroupDispatcher(group)

            truck_dispatch_plan_dict = group_dispatcher.group_dispatch(ExpectedTime)

            if truck_dispatch_plan_dict is None:
                logger.error(f'分组 {group.group_id} 调度异常')
        except Exception as es:
            logger.error(es)
            logger.error(f'分组{group.group_id} 调度计算异常')

        try:

            logger.info(f'调度分组: {group.group_id} {DispatchInfo.group_name[group.group_id]}')
            submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict)
        except Exception as es:
            group_direct2redis(group)
            logger.error(es)
            logger.error(f'分组{group.group_id} 调度写入异常')


    except Exception as es:
        logger.error("最外层异常捕获")
        logger.error(es)
        return jsonify(msg="未知异常, 请联系管理员", code=505)

    session_mysql.close()
    session_postgre.close()

    logger.info("#####################################请求调度更新结束#####################################")

    # 调度结束时间
    rtd_end_time = datetime.now()

    print(f'调度时耗 {rtd_end_time - rtd_start_time}')

    return jsonify(msg="success", code=0)