# -*- coding:utf-8 -*-

"""
python AI推演开始模块, 在此模块中启动
"""
import time

import tensorflow as tf
from corekit.config.base import TaskConfigAPI
from agent.config import LingYiConfig
from engine.LingYi.entitys.deduce_RL import Deduction


def main():
    """
    启动运行函数
    :return: str, game result
    """
    """
    加载灵弈智能体环境配置
    查看是否有强化学习智能体，如果有：就启动rllib框架
    没有：就不启动rllib框架训练
    """
    rl_agents = LingYiConfig.get_rl_agent()
    have_rl_agent = False  # 是否有强化学习
    for side, agent_info in rl_agents.items():
        if "agents" in agent_info and agent_info["agents"]:
            have_rl_agent = True
            break
    if have_rl_agent:
        # 有强化学习,由ray框架学习训练
        task_config = TaskConfigAPI('LingYi').build(mode='train', category='tune')
        all_config = task_config.get_all_config()
        task_config.from_dict(config=all_config)
        task_config.start()
    else:
        # 当推理应用时强制启用 Eager 模式; 计算图模式不支持神经网络模型输出的Tensor直接转换为numpy
        # 如强化学习智能体推理应用，需设置为True
        tf.config.run_functions_eagerly(True)

        config = LingYiConfig.get_server_config({})
        config.update(LingYiConfig.get_rule_config({}))
        lingyi_env = Deduction(config)
        episodes = 1
        if "episodes" in config["game_server"]["simulate"]:
            episodes = config["game_server"]["simulate"]["episodes"]
        train_episode = 1
        while True:
            reset_result = 0
            for i in range(3):
                # 尝试3次
                reset_result = lingyi_env.reset(train_episode)
                if reset_result == 1:
                    # 1：成功， 0:管理服务连接出错， -1: 推演服务连接失败,-2:后台无推演想定，-3：没有获取后台初始态势
                    break
                time.sleep(3)
            if reset_result != 1:
                # 连接后台问题或无想定问题，终止运行智能体
                print("连接后台或想定出错，标志:%d, 退出运行智能体！" % reset_result)
                break
            while True:
                lingyi_env.step({})  # 智能体决策和步进推演
                if lingyi_env.is_done():
                    # 推演结束或训练时智能体判断结束本局，或推演后台崩溃等问题
                    break
            train_episode += 1
            if train_episode > episodes:
                # 已到设定的推演局数，终止
                break

    input("推演结束，请按任意键退出...\n")


if __name__ == '__main__':
    main()
