%% ---------------------------------------------------------------------------
%% @doc tool.erl
%% @author ming_up@foxmail.com
%% @since  2016-02-17
%% @deprecated 工具类，辅助分析类函数
%% ---------------------------------------------------------------------------
-module(tool).
-compile(export_all).

-include("common.hrl").

%%获取客户端ip
get_ip(Socket) ->
    case inet:peername(Socket) of
        {ok, {Ip, _Port}} -> Ip;
        {error, _Reason} -> {0,0,0,0}
    end.

%% IP元组转字符
ip2bin(IpBinary) when is_binary(IpBinary)-> binary_to_list(IpBinary);
ip2bin(IpList) when is_list(IpList)-> IpList;
ip2bin({A, B, C, D}) ->
    [integer_to_list(A), ".", integer_to_list(B), ".", integer_to_list(C), ".", integer_to_list(D)].


%% node输出ip
node_to_ip(Node) ->
    case split_node(atom_to_list(Node), $@, []) of
        [_, Host] -> inet:getaddr(Host, inet);
        _ -> no_node_name
    end.

split_node([Chr|T], Chr, Ack) -> [lists:reverse(Ack)|split_node(T, Chr, [])];
split_node([H|T], Chr, Ack)   -> split_node(T, Chr, [H|Ack]);
split_node([], _, Ack)        -> [lists:reverse(Ack)].

%% 输出进程为error,error_report,crash_report,warning_report到"../logs/rb.txt"
rb() ->
    %% 路径
    Path = "../logs/rb.txt",
    %% 日期
    {{Y, M, D},{H, I, S}} = erlang:localtime(),
    Format  = list_to_binary("============start data: ~s =============\r\n~n"),
    Date    = list_to_binary(lists:concat([Y,"-",M,"-",D," ",H,":",I,":",S])),
    %% 输入日期
    {ok, F} = file:open(Path, [write, append]),
    io:format(F, unicode:characters_to_list(Format), [Date]),
    file:close(F),
    %% rb模块
    rb:start([{start_log, Path}, {type, [error,error_report,crash_report,warning_report]}]),
    rb:show(error),
    rb:show(error_report),
    rb:show(crash_report),
    rb:show(warning_report),
    ok.

%% 堆栈输出
back_trace() ->
    io:format("  ~p~n~n", [?CURR_STACK()]).
    % lists:foldl(
    %   fun({M, F, ArgNum, [{_File, _FileName}, {_Line, Line}]}, N) ->
    %           io:format("~s~p:~p/~p [line:~p]~n", [lists:append(lists:duplicate(N, " ")), M, F, ArgNum, Line]),
    %           N + 2 end, 0, try throw(42) catch 42 -> erlang:get_stacktrace()
    %                                       end
    %  ).

%% 堆栈文件输出
back_trace_to_file() ->
    ?INFO("  ~p", [?CURR_STACK()]).
    % lists:foldl(
    %   fun({M, F, ArgNum, [{_File, _FileName}, {_Line, Line}]}, N) ->
    %           ?INFO("~s~p:~p/~p [line:~p]~n", [lists:append(lists:duplicate(N, " ")), M, F, ArgNum, Line]),
    %           N + 2 end, 0, try throw(42) catch 42 -> erlang:get_stacktrace()
    %                                       end
    %  ).

%% 生成错误码数据库txt
%% base_error_code:module,type,id,about
%% test: tool:create_error_code_sql("E:\\ZiSu\\xgame\\x_kf\\code\\erl\\src", 400)
create_error_code_sql(DirStr, Pt) ->
    FilenameList = get_filename_list(DirStr),
    {ok, MatchPattern} = re:compile(lists:concat(["err", Pt, "_\\w*"])),
    F = fun(Filename, TmpList) ->
                {ok, ContentBin} = file:read_file(Filename),
                Content = binary_to_list(ContentBin),
                case re:run(Content, MatchPattern, [global,{capture,first,list}]) of
                    {match, MatchList} -> MatchList ++ TmpList;
                    _ -> TmpList
                end
        end,
    List = lists:foldl(F, [], FilenameList),
    F2 = fun([T], L) ->
                 Atom = list_to_atom(T),
                 case lists:member(Atom, L) of
                     true -> L;
                     false -> [Atom|L]
                 end;
            (_, L) ->
                 L
         end,
    TypeList = lists:foldl(F2, [], List),
    F3 = fun(Type) ->
                 case data_error_code:get(Type) of
                     0 -> {Type, 0, ""};
                     Id ->
                         case data_errorcode_msg:get(Id) of
                             #errorcode_msg{about = About} -> ok;
                             _ -> About = ""
                         end,
                         {Type, Id, About}
                 end
         end,
    TupleList = lists:map(F3, TypeList),
    SortList = lists:reverse(lists:keysort(2, TupleList)),
    case SortList of
        [] -> Max = 0;
        _ -> {_, Max, _} = hd(SortList)
    end,
    F4 = fun({Type, Id, About}, {TmpList, TmpMax}) ->
                 case Id == 0 of
                     true -> { [{Type, TmpMax+1, About}|TmpList], TmpMax+1};
                     false -> { [{Type, Id, About}|TmpList], TmpMax}
                 end
         end,
    {NewSortList, _} = lists:foldr(F4, {[], Max}, SortList),
    NewSortList2 = lists:keysort(2, NewSortList),
    create_error_code_sql_done(NewSortList2, Pt, "").

create_error_code_sql_done([], _Pt, Acc) ->
    {ok, F} = file:open("../logs/errcode_" ++ integer_to_list(_Pt) ++ util:term_to_string(calendar:now_to_datetime(os:timestamp())), [write]),
    io:format(F, iolist_to_binary(Acc), []);
create_error_code_sql_done([{Type, Id, About}|L], Pt, Acc) ->
    Sql = "REPLACE INTO base_error_code(module, type, id, about) VALUES({1}, '{2}', {3}, '{4}');\n",
    Str = uio:format(Sql, [Pt, Type, Id, About]),
    create_error_code_sql_done(L, Pt, lists:concat([Acc, Str])).

test_create_error_code_sql() ->
    {ok, ContentBin} = file:read_file("D:\\erl_work\\st_project\\st_kf\\code\\erl\\src\\guild\\lib_guild_mod.erl"),
    Content = binary_to_list(ContentBin),
    {ok, MatchPattern} = re:compile(lists:concat(["err", 400, "_\\w*"])),
    re:run(Content, MatchPattern, [global,{capture, first,list}]).

%% 获取所有的文件名字列表
get_filename_list(Dir) when is_list(Dir) ->
    get_filename_list([Dir], []).

get_filename_list([], Acc) ->
    Acc;
get_filename_list([File|Tail], Acc) ->
    case filelib:is_dir(File) of
        true ->
            case file:list_dir(File) of
                {ok, NewFiles} ->
                    FullNewFiles = [filename:join(File, N) || N <- NewFiles],
                    get_filename_list(FullNewFiles ++ Tail, Acc);
                {error, _Reason} ->
                    get_filename_list(Tail, Acc)
            end;
        false ->
            get_filename_list(Tail, [File | Acc])
    end.
