%%%----------------------------------------------------------------------
%%% File    : erl1.erl
%%% Author  : Jason Allen <jason@ohloh.net> - kinda - just repurposing random code
%%% Purpose : Test out the erlang parsing
%%% Created : 1/17/2007 by Jason Allen <jason@ohloh.net>
%%% Id      : $Id: erl1.erl 1 2007-17-01 jason $
%%%----------------------------------------------------------------------

-module(erl1).
-author('jason@ohloh.net').
-vsn('$Revision: 1 $ ').

%% External exports
-export([import_file/1,
	 import_dir/1]).

-include("random.hrl").
-include("more_random.hrl").

%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------

import_file(File) ->
    User = filename:rootname(filename:basename(File)),
    Server = filename:basename(filename:dirname(File)),
    case (jlib:nodeprep(User) /= error) andalso
	(jlib:nameprep(Server) /= error) of
	true ->
	    case file:read_file(File) of
		{ok, Text} ->
		    case xml_stream:parse_element(Text) of
			El when element(1, El) == xmlelement ->
			    case catch process_xdb(User, Server, El) of
				{'EXIT', Reason} ->
				    ?ERROR_MSG(
				       "Error while processing file \"~s\": ~p~n",
				       [File, Reason]),
				       {error, Reason};
				_ ->
				    ok
			    end;
			{error, Reason} ->
			    ?ERROR_MSG("Can't parse file \"~s\": ~p~n",
				       [File, Reason]),
			    {error, Reason}
		    end;
		{error, Reason} ->
		    ?ERROR_MSG("Can't read file \"~s\": ~p~n", [File, Reason]),
		    {error, Reason}
	    end;
	false ->
	    ?ERROR_MSG("Illegal user/server name in file \"~s\"~n", [File]),
	    {error, "illegal user/server"}
    end.


import_dir(Dir) ->
    {ok, Files} = file:list_dir(Dir),
    MsgFiles = lists:filter(
		 fun(FN) ->
			 case string:len(FN) > 4 of
			     true ->
				 string:substr(FN,
					       string:len(FN) - 3) == ".xml";
			     _ ->
				 false
			 end
		 end, Files),
    lists:foldl(
      fun(FN, A) ->
	      Res = import_file(filename:join([Dir, FN])),
	      case {A, Res} of
		  {ok, ok} -> ok;
		  {ok, _} -> {error, "see aoabberd log for details"};
		  _ -> A
	      end
      end, ok, MsgFiles).

%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------

process_xdb(User, Server, {xmlelement, Name, _Attrs, Els}) ->
    case Name of
	"xdb" ->
	    lists:foreach(
	      fun(El) ->
		      xdb_data(User, Server, El)
	      end, Els);
	_ ->
	    ok
    end.


xdb_data(User, Server, {xmlcdata, _CData}) ->
    ok;
xdb_data(User, Server, {xmlelement, _Name, Attrs, _Els} = El) ->
    From = jlib:make_jid(User, Server, ""),
    LServer = jlib:nameprep(Server),
    case xml:get_attr_s("xmlns", Attrs) of
	?NS_AUTH ->
	    Password = xml:get_tag_cdata(El),
	    ejabberd_auth:set_password(User, Server, Password),
	    ok;
	?NS_ROSTER ->
	    case lists:member(mod_roster_odbc,
			      gen_mod:loaded_modules(LServer)) of
		true ->
		    catch mod_roster_odbc:set_items(User, Server, El);
		false ->
		    catch mod_roster:set_items(User, Server, El)
	    end,
	    ok;
	?NS_LAST ->
	    TimeStamp = xml:get_attr_s("last", Attrs),
	    Status = xml:get_tag_cdata(El),
	    case lists:member(mod_last_odbc,
			      gen_mod:loaded_modules(LServer)) of
		true ->
		    catch mod_last_odbc:store_last_info(
			    User,
			    Server,
			    list_to_integer(TimeStamp),
			    Status);
		false ->
		    catch mod_last:store_last_info(
			    User,
			    Server,
			    list_to_integer(TimeStamp),
			    Status)
	    end,
	    ok;
	?NS_VCARD ->
	    case lists:member(mod_vcard_odbc,
			      gen_mod:loaded_modules(LServer)) of
		true ->
		    catch mod_vcard_odbc:process_sm_iq(
			    From,
			    jlib:make_jid("", Server, ""),
			    #iq{type = set, xmlns = ?NS_VCARD, sub_el = El});
		false ->
		    catch mod_vcard:process_sm_iq(
			    From,
			    jlib:make_jid("", Server, ""),
			    #iq{type = set, xmlns = ?NS_VCARD, sub_el = El})
	    end,
	    ok;
	"jabber:x:offline" ->
	    process_offline(Server, From, El),
	    ok;
	XMLNS ->
	    case xml:get_attr_s("j_private_flag", Attrs) of
		"1" ->
		    catch mod_private:process_sm_iq(
			    From,
			    jlib:make_jid("", Server, ""),
			    #iq{type = set, xmlns = ?NS_PRIVATE,
				sub_el = {xmlelement, "query", [],
					  [jlib:remove_attr(
					     "j_private_flag",
					     jlib:remove_attr("xdbns", El))]}});
		_ ->
		    ?DEBUG("jd2ejd: Unknown namespace \"~s\"~n", [XMLNS])
	    end,
	    ok
    end.


process_offline(Server, To, {xmlelement, _, _, Els}) ->
    LServer = jlib:nameprep(Server),
    lists:foreach(fun({xmlelement, _, Attrs, _} = El) ->
			  FromS = xml:get_attr_s("from", Attrs),
			  From = case FromS of
				     "" ->
					 jlib:make_jid("", Server, "");
				     _ ->
					 jlib:string_to_jid(FromS)
				 end,
			  case From of
			      error ->
				  ok;
			      _ ->
				  ejabberd_hooks:run(offline_message_hook,
						     LServer,
						     [From, To, El])
			  end
		  end, Els).

