%%% -----------------------------------------
%%% @author huangyongxing@yeah.net
%%% @doc
%%% 游戏服主节点监控树
%%% 2016-11-18
%%% @end
%%% -----------------------------------------
-module(game_master_sup).
-behaviour(supervisor).
%% API
-export([
        start_link/1
        ,stop/0
        ,do_start/2
    ]).
%% Supervisor callbacks
-export([init/1]).

-include("common.hrl").
-include("def_id_create.hrl").
-include("def_id_create_extra.hrl").
-include("def_module.hrl").

-define(SERVER, ?MODULE).

%% 启动监控树
start_link([StrHost, StrPort | _]) ->
    Host = list_to_binary(StrHost),
    Port = list_to_integer(StrPort),
    pre_start(),
    Ret = supervisor:start_link({local, ?SERVER}, ?MODULE, [Host, Port]),
    aft_start(),
    Ret.

%% init(Args) -> {ok, {RestartStrategy, Children}}.
%% Args : list(),
%% RestartStrategy : {one_for_one, MaxR, MaxT},
%% Children : [ChildSpec].
init([Host, Port]) ->
    ?INFO_TTY("Start supervisor [~w] ...", [?SERVER]),
    %% {RestartStrategy, MaxR, MaxT}, MaxT秒内超过MaxR次重启，即停止监控树和子进程
    RestartStrategy = {one_for_one, 50, 5},
    Children = get_children([Host, Port]),
    {ok, {RestartStrategy, Children}}.

%% 正常关服流程回调
%% （监控树意外挂掉不走这里，如需保证执行，在shutdown_mgr中添加处理）
%% 注意，这里的关服操作完成之后，才调用application:stop/1关闭application（关闭监控树）
stop() ->
    %% 停止接受新连接
    game_listener:stop(),
    % application:stop(inets),
    ok.

get_children([Host, Port]) ->
    %% 监控树策略：{Id, StartFunc = {_, _, _}, Restart, Shutdown, Type, Modules}
    ListNormalStart = [     % 一般功能模块及监控树启动
        {mod_scene_mon, start_link, []}                                 % 场景mon进程
        ,{mod_scene_npc, start_link, []}                                % 场景npc进程
        ,{scene_mgr, start_link,[]}                                     % 场景进程池管理进程
        ,{timer_quest, start_link, []}                                  % 动态定时器
        ,{mod_cache, start_link, []}                                    % key_value缓存服务
        ,{mod_act_join, start_link, []}                                 % 活动参与记录服务
        ,{mod_id_create, start_link, [?GOODS_ID_CREATE]}                % 物品自增Id
        ,{mod_id_create, start_link, [?GUILD_ID_CREATE]}                % 公会自增Id
        ,{mod_id_create, start_link, [?AUCTION_ID_CREATE]}              % 拍卖场次id
        ,{mod_id_create, start_link, [?AUCTION_GOODS_ID_CREATE]}        % 拍卖物品id
        ,{mod_id_create, start_link, [?SELL_ID_CREATE]}                 % 交易自增id
        ,{mod_id_create, start_link, [?CHARGE_PAY_NO_CREATE]}           % 充值订单号(只用于秘籍)
        ,{mod_id_create, start_link, [?FLOWER_GIFT_RECORD_ID_CREATE]}   % 鲜花送礼记录id
        ,{mod_id_create, start_link, [?RED_ENVELOPES_ID_CREATE]}        % 红包自增id
        ,{mod_id_create, start_link, [?ORDER_ID_CREATE]}                % 任务单自增id
        ,{mod_id_create, start_link, [?SUPPORT_ID_CREATE]}              % 社团协助自增id
        ,{ta_agent, start_link, []}                                     % 数数TA分析系统上报代理
        ,{mod_chat_agent, start_link, []}                               % 聊天
        ,{mod_common_rank, start_link, []}                              % 排行榜
        ,{mod_chat_voice, start_link, []}                               % 语音和图片
        ,{mod_chat_forbid, start, []}                                   % 禁言
        ,{mod_chat_cache, start_link, []}                               % 聊天缓存
        ,{mod_chat_bugle, start_link, []}                               % 喇叭
        ,{chat_monitor_agent, start_link, []}                           % 聊天监控
        ,{mod_daily_dict, start_link, []}                               % 日常次数（缓存版）
        ,{mod_ban, start_link, []}                                      % 封号
        ,{online_monitor, start_link, []}                               % 在线资源监控、数据库心跳
        ,{scene_enter_queue, start_link, []}                            % 场景排队进入管理
        ,{mod_player_create, start_link, []}                            % 玩家id
        ,{mod_team_create, start_link, []}                              % 组队id
        ,{mod_team_enlist, start_link, []}                              % 组队招募平台
        ,{mod_crontab, start_link, []}                                  % cron服务进程
        ,{timer_min, start_link, []}                                    % 分钟定时器
        ,{timer_hour, start_link, []}                                   % 小时定时器
        ,{timer_midnight, start_link, []}                               % 晚上十二点
        ,{timer_4_clock, start_link, []}                                % 凌晨4点
        ,{mod_custom_act, start_link, []}                               % 定制活动
        ,{mod_drop, start_link, []}                                     % 物品掉落
        ,{timer_custom, start_link, []}                                 % 活动定时器
        ,{mod_guild_boss_mgr, start_link,[]}                            % 社团BOSS
        ,{mod_offline_player, start_link, []}                           % 离线玩家
        ,{mod_guild, start_link, []}                                    % 公会
        ,{mod_guild_support, start_link, []}                            % 公会协助
        ,{mod_dungeon_agent, start_link, []}                            % 副本管理
        ,{mod_pushmail, start_link, []}                                 % 邮件推送
        ,{mod_arena, start_link, []}                                    % 竞技场
        ,{mod_recharge_act, start_link, []}                             % 充值活动(每日礼包)
        ,{mod_red_envelopes, start_link, []}                            % 公会红包
        ,{mod_global_counter, start_link, []}                           % 单服计数器
        ,{mod_top_pk_local, start_link, []}                             % 巅峰竞技本服
        ,{mod_top_pk_match, start_link, []}                             % 巅峰竞技匹配
        ,{mod_charm_beach, start_link, []}                              % 魅力海滩
        ,{mod_rush_rank, start_link, []}                                % 开服冲榜
        ,{mod_limit_buy, start_link, []}                                % 特惠商城
        ,{mod_smashed_egg, start_link, []}                              % 砸蛋
        ,{mod_perfect_lover, start_link, []}                            % 完美恋人
        ,{boss_first_blood, start_link, []}                             % boss首杀
        ,{mod_hi_point, start_link, []}                                 % 嗨点
        ,{mod_lucky_turntable, start_link, []}                          % 幸运转盘
        ,{mod_cloud_buy_local, start_link, []}                          % 众仙云购本地
        ,{mod_cloud_buy_mgr, start_link, []}                            % 众仙云购
        ,{mod_auction, start_link, []}                                  % 拍卖行(跟在活动参与记录服务后面)
        ,{mod_3v3_local, start_link, []}                                % 3v3
        ,{mod_kf_1vn_local, start_link, []}                             % 跨服1vn
        ,{mod_gift_card, start_link, []}                                % 礼包管理进程
        ,{mod_local_supplication, start_link, []}                       % 祈愿local进程
        ,{mod_consume_rank_act, start_link, []}                         % 充值消费榜
        ,{mod_growth_score, start_link, []}                             % 成长积分活动
        ,{mod_draw_record_local, start_link, []}                        % 本服抽奖记录进程
        ,{mod_pet_support_mgr, start_link, []}                          % 宠物全服支援管理进程
        ,{mate_mgr, start_link, []}                                     % 羁绊管理器
        ,{exp_dun_drop_mgr, start_link, []}                             % 放置经验公共进程
        ,{mod_child_vote_mgr, start_link, []}                           % 孩子点赞排行榜管理进程
        ,{mod_glamour_ctrl, start_link, []}
        ,{mod_glamour_mgr, start_link, []}
        ,{mod_glamour_focus, start_link,[]}
        ,{mod_void_fam_local, start_link, []}                           % 无尽领域
        ,{mod_guild_tribe_mgr, start_link, []}                          % 社团驻地
        ,{guild_war_mgr, start_link,[]}                                 % 本服公会战
        ,{world_boss_mgr, start_link, []}                               % 本服BOSS
        ,{reward_boss_mgr, start_link, []}                              % 赏金BOSS
        ,{guild_collect_mgr, start_link, []}                            % 社团午间采集
        ,{mod_capsule_egg, start_link, []}                              % 龙神扭蛋管理进程
        ,{mod_dun_pet_rank, start_link, []}                             % 宠物副本排行榜管理进程
        ,{mod_custom_act_log,start_link,[]}                             % 定制活动全服记录进程
        ,{mod_guild_race_rank, start_link, []}                          % 公会竞榜
        ,{race_rank_act_local,start_link,[]}                            % 跨服竞榜游戏服活动管理
        ,{cross_guild_war_local,start_link,[]}
        ,{group_buy_mgr, start_link, []}                                % 团购活动
        ,{svr_vitality_local_mgr, start_link, []}                       % 游戏服活跃管理
        ,{custom_act_pellet_mgr, start_link, []}                        % 弹珠活动奖励记录
        ,{treasure_house_mgr, start_link, []}                           % 珍宝阁抽奖传闻记录
        ,{god_lottery, start_link,[]}                                   % 唤神抽奖
        ,{offline_hosting, start_link,[]}                               % 离线托管
        ,{god_dun_rank_local, start_link, []}                           % 唤神副本本地管理
        ,{mod_mobilize_mgr, start_link, []}                             % 全民动员总程管理
        ,{madness_land, start_link,[]}                                  % 狂战领域
        ,{mod_wasteland_war, start_link, []}                            % 废土战场(饥饿游戏)本服管理
        ,{limit_mail_mgr, start_link, []}                               % 限时邮件
        ,{beauty_contest, start_link, []}                               % 靓丽大赛
        ,{mod_unite_buff_mgr, start_link, []}                           % 材料上交 联合buff
        ,{merge, start_link, []}                                        % 合服处理
        ,{deserted_boss_mgr, start_link, []}                            % 废都BOSS
        ,{seckill_local, start_link, []}                                % 秒杀活动
        ,{mod_lucky_bag_ctrl,start_link,[]}
        ,{cross_rank_local, start_link, []}                             % 跨服排行本地管理
        ,{market_mgr, start_link, []}                                   % 交易市场管理进程
        ,{tarot_log_mgr, start_link, []}                                % 塔罗牌日志管理
        ,{act_boss_mgr, start_link, []}                                 % 活动BOSS
        ,{guard_dun_assist_local, start_link, []}                       % 守卫信标支援榜单
        ,{printer_draw, start_link, []}                                 % 合成机
        ,{mod_convert_mgr, start_link, []}                              % 物品转换管理
        ,{local_legion_mgr,start_link, []}                              % 本地指挥室
        ,{cross_point_fight_local, start_link, []}                      % 跨服沙盘本服管理
        ,{camp_war_mgr, start_link, []}                                 % 本地团战
        ,{mod_military_rank_local, start_link, []}                      % 军衔榜本地管理
        ,{mod_treasure_map_advance, start_link, []}                     % 高级藏宝图管理进程
        ,{guild_run_assist, start_link, []}
        ,{visus_dun_rank, start_link, []}                               % 幻光排行
        ,{tower_dun_rank, start_link, []}                               % 爬塔副本排行
        ,{exp_dun_wave_rank, start_link, []}                            % 经验副本波数排行
        % ,{mod_prevent_addiction, start_link, []}                        % 防沉迷管理进程
        ,{home_boss_mgr, start_link, [?MOD_HOME_BOSS_NORMAL]}           % 幻魔之家
        ,{home_boss_mgr, start_link, [?MOD_HOME_BOSS_GUILD]}            % 社团之家
        ,{mod_exp_sea, start_link, []}                                  % 经验海
    ],
    ListFirstStart = [      % 其他依赖内容，最早启动
        {game_env, start_link, [?SERVER]}
        ,{node_mgr, start_link, [{Host, Port}]}
        ,{game_init, start_link, []}
        ,{mod_scene_object_create, start_link, []}
        ,{mod_log, start_link, []}
        ,{mod_mail, start_link, []}                                     % 邮件管理
    ],
    ListLastStart = [       % 最后启动内容
        {clusters_node, start_link, []}

        %% 这几项固定放最后，确保监控树关闭时先关入口，保存玩家数据及其他清理操作
        ,{shutdown_mgr, start_link, []}
        ,{{game_acceptor_sup, start_link, []}, supervisor}
        ,{game_listener, start_link, [Port]}
        ,{mod_activitycalen, start_link, []}                            % 活动日历
    ],
    %% 数据库连接
    DbChildSpecList = db:child_spec_list(),
    [
        case format_child(ChildInfo) of
            false -> throw(error);
            Child -> Child
        end || ChildInfo <- DbChildSpecList ++ ListFirstStart ++ ListNormalStart ++ ListLastStart
    ].

%% 将简易配置转换为supervisor的childspec格式
format_child({mod_id_create = Mod, Fun, Args}) ->
    ChildName = [Mod | Args],
    {ChildName, {Mod, Fun, Args}, permanent, 10000, worker, [Mod]};
format_child({home_boss_mgr = Mod, Fun, Args}) ->
    ChildName = [Mod | Args],
    {ChildName, {Mod, Fun, Args}, permanent, 10000, worker, [Mod]};
format_child({Mod, Fun, Args}) ->
    {Mod, {Mod, Fun, Args}, permanent, 10000, worker, [Mod]};
format_child({StartFunc = {Mod, _, _}, {child_name, ChildName}}) ->
    {ChildName, StartFunc, permanent, 10000, worker, [Mod]};
format_child({StartFunc = {Mod, _, _}, Type}) ->
    {Mod, StartFunc, permanent, 10000, Type, [Mod]};
format_child(Child = {_ChildName, _StartFunc = {_, _, _}, _Restart, _Shutdown, _Type, _Modules}) ->
    Child;
format_child(_) ->
    ?ERR_TTY("监控树错误格式"),
    false.

%% 非监控树中启动的内容，但是可能是依赖项
pre_start() ->
    application:set_env(kernel, dist_auto_connect, never),
    %% httpc默认参数：
    %% max_sessions 与主机的最大持久连接数，默认为2
    %% keep_alive_timeout默认为120秒(120000)，
    %% max_keep_alive_length默认为5，即同一连接允许有5个未完成的请求（第一个阻塞，会影响后面的请求）
    HttpcOptions = [{max_keep_alive_length, 2}],
    httpc:set_options(HttpcOptions),
    %% 程序运行日志logger管理
    logger_game_h:init_log(),
    ok.

%% 非监控树中启动的内容，但是依赖于监控树中启动的内容
aft_start() ->
    ok.

do_start(SupRef, ChildSpec = {_Id, _StartFunc = {_, _, _}, _Restart, _Shutdown, _Type, _Modules}) ->
    ?INFO_TTY("start child [~w]", [_Id]),
    Ret = supervisor:start_child(SupRef, ChildSpec),
    ?INFO_TTY("start child [~w] finished, result [~w]", [_Id, Ret]),
    ChildSpec;
do_start(_, _) ->
    ignore.
