%% Copyright (c) 2010, Huiqing Li, Simon Thompson 
%% All rights reserved. 
%%
%% Redistribution and use in source and binary forms, with or without
%% modification, are permitted provided that the following conditions are met:
%%     %% Redistributions of source code must retain the above copyright
%%       notice, this list of conditions and the following disclaimer.
%%     %% Redistributions in binary form must reproduce the above copyright
%%       notice, this list of conditions and the following disclaimer in the
%%       documentation and/or other materials provided with the distribution.
%%     %% Neither the name of the copyright holders nor the
%%       names of its contributors may be used to endorse or promote products
%%       derived from this software without specific prior written permission.
%%
%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS''
%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
%% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
%% BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
%% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
%% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
%% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%% =====================================================================
%% Refactoring Interface Functions.
%%
%% Author contact: H.Li@kent.ac.uk, Simon.J.Thompson@kent.ac.uk
%%
%% =====================================================================

%% @copyright 2006-2010 Huiqing Li, Simon Thompson
%%
%% @author Huiqing Li, Simon Thompson
%%   [http://www.cs.kent.ac.uk/projects/wrangler]

%% @version 0.8.7
%% @end
%%
%% @doc This module describes the refactorings that are currently supported by Wrangler.
-module(wrangler).

-export([refac_Lista/1,refac_Import/1,refac_CaseFun/1]).

-export([refac_Lista_eclipse/1,refac_Import_eclipse/1,refac_CaseFun_eclipse/1]).

-export([try_refactoring/3, try_inspector/3, get_log_msg/0]).

-export([init_eclipse/0]).
-include("../include/wrangler.hrl").




%%======================================================================================
%%======================================================================================
%%======================================================================================
%%======================================================================================
%%======================================================================================

-spec(refac_Lista/1::(filename()) -> 
	     {error, string()} | {question, string()} | {warning, string()} |{ok, [filename()]}).
refac_Lista(FileName) ->
    try_refactoring(refac2_Lista, refac_Lista,  [FileName]).

%%@private
-spec(refac_Lista_eclipse/1::(FileName::filename()) ->
	     {error, string()} | {question, string()} | {warning, string()} |
		 {ok, [{filename(), filename(), string()}]}).
refac_Lista_eclipse(FileName) ->
    try_refactoring(refac2_Lista, refac_Lista_eclipse, [FileName]).
%%======================================================================================
%%======================================================================================
%%======================================================================================
%%======================================================================================
%%======================================================================================

-spec(refac_Import/1::(filename()) -> 
	     {error, string()} | {question, string()} | {warning, string()} |{ok, [filename()]}).
refac_Import(FileName) ->
    try_refactoring(refac2_Import, refac_Import,  [FileName]).

%%@private
-spec(refac_Import_eclipse/1::(FileName::filename()) ->
	     {error, string()} | {question, string()} | {warning, string()} |
		 {ok, [{filename(), filename(), string()}]}).
refac_Import_eclipse(FileName) ->
    try_refactoring(refac2_Import, refac_Import_eclipse, [FileName]).
%%======================================================================================
%%======================================================================================
%%======================================================================================
%%======================================================================================
%%======================================================================================

-spec(refac_CaseFun/1::(filename()) -> 
	     {error, string()} | {question, string()} | {warning, string()} |{ok, [filename()]}).
refac_CaseFun(FileName) ->
    try_refactoring(refac2_CaseFun, refac_CaseFun,  [FileName]).

%%@private
-spec(refac_CaseFun_eclipse/1::(FileName::filename()) ->
	     {error, string()} | {question, string()} | {warning, string()} |
		 {ok, [{filename(), filename(), string()}]}).
refac_CaseFun_eclipse(FileName) ->
    try_refactoring(refac2_CaseFun, refac_CaseFun_eclipse, [FileName]).
%%======================================================================================
%%======================================================================================
%%======================================================================================
%%======================================================================================
%%======================================================================================


%%@private
try_to_apply(Mod, Fun, Args, Msg) -> 
    apply(Mod, Fun, Args).
%% 	try apply(Mod, Fun, Args)
%%      catch
%% 	 throw:Error -> 
%% 	     Error;    %% wrangler always throws Error in the format of '{error, string()}';
%% 	 _E1:_E2->
%%      	     %%refac_io:format("E1E2:\n~p\n", [{E1, E2}]),
%% 	     {error, Msg}
%%      end.

%%@private
try_refactoring(Mod, Fun, Args) ->
    Msg = "Wrangler failed to perform this refactoring, "
	"please report error to erlang-refactor@kent.ac.uk.",
    try_to_apply(Mod, Fun, Args, Msg).

%%@private
try_inspector(Mod, Fun, Args) -> 
    Msg ="Wrangler failed to perform this functionality, "  
	"please report error to erlang-refactor@kent.ac.uk.",
    try_to_apply(Mod, Fun, Args, Msg).


%%@private
init_eclipse() ->
    application:start(wrangler_app).
    


get_log_msg() ->
    Errors = wrangler_error_logger:get_logged_info(),
    FileErrors = [{File, Error} || {File, Error} <- Errors, File /= warning],
    ErrorMsg= 
	case FileErrors of 
	    [] -> "";
	    _ ->
		Msg1=io_lib:format("There are syntax errors, or syntaxes not supported by Wrangler;"
				   " functions/attribute containing these syntaxes are not affected by the refactoring.\n", []),
		Msg2 = lists:flatmap(fun ({FileName, Errs}) ->
					     Str = io_lib:format("File:\n ~p\n", [FileName]),
					     Str1 = Str ++ io_lib:format("Error(s):\n", []),
					     Str1 ++ lists:flatmap(fun (E) ->
									   case E of
									       {Pos, _Mod, Msg} -> io_lib:format(" ** ~p:~p **\n", [Pos, Msg]);
									       M -> io_lib:format("**~p**\n", [M])
									   end
									 end,
								   lists:reverse(Errs))
				     end, Errors),
		Msg1++Msg2
	end,
    WarningMsg=case lists:keysearch(warning, 1, Errors) of 
		   {value, {warning, Str}} ->
		       Str;
		   false -> ""
	       end,
    ErrorMsg++WarningMsg.
   
