package reseau;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * User: Andréa
 * Date: 23/12/10
 * Time: 02:26
 */
abstract class MessageAbstractFactory {

    private static final Map<FactoryType, MessageAbstractFactory> factories = new HashMap<FactoryType, MessageAbstractFactory>();

    static {
        factories.put(FactoryType.GROUP, new GroupMessageFactory());
        factories.put(FactoryType.PROBLEM, new ProblemMessageFactory());
        factories.put(FactoryType.RESULT, new ResultMessageFactory());
        factories.put(FactoryType.USER, new UserMessageFactory());
        factories.put(FactoryType.BENCHMARK, new BenchmarkMessageFactory());
        factories.put(FactoryType.MANAGEMENT, new ManagementMessageFactory());
    }

    public static MessageAbstractFactory getFactory(FactoryType type) {
        return factories.get(type);
    }

    abstract public Message createMessage(Message.MessageAction action);

    public static Message createResponseMessage(String data) throws DataNotFoundException, UnauthorizedOperationException {
    	System.out.println("*************************************data : "+data);
    	Scanner responseScanner = new Scanner(data);
        String line = null;
        Message response = new Message();

        //Analyse first line : server response status code
        line = responseScanner.nextLine();

        //HELP : Sample line : HTTP/1.0 200 OK
        response.addParameter(Message.MessageParameter.STATUS_CODE, line.split(" ")[1]);

        //HELP Analyse status code : 404 [Not found], 403[Forbidden] & Throw Exception
        // 2xx              : http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success
        // 4xx Client Error : http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error
        int response_code = Integer.parseInt(response.extract(Message.MessageParameter.STATUS_CODE));
        switch (response_code) {
            case 404:
                throw new DataNotFoundException("Requested resource not found");
            case 403:
                throw new UnauthorizedOperationException("Current user is not able to access this resource");
            case 409:
                throw new UnauthorizedOperationException("An existing resource is in conflict with yours");
            case 412:
                throw new UnauthorizedOperationException("Precondition failed, check if files has been correctly transferred");
            default:
                break;
        }

        // header-content separator
        
        //System.out.println("params : "+line);
        while (!(line = responseScanner.nextLine()).equals("")) {
            Message.MessageParameter headerParameter = selectParameter(line);
            //System.out.println("params : "+line);
            if (headerParameter != null) {
                String content = line.substring( line.indexOf(':') + 1).trim();
                response.addParameter(headerParameter, content);
            }
        }

        // Reading content
        while (responseScanner.hasNextLine()){
        	String test = responseScanner.nextLine();
        	//System.out.println("responseScanner: "+test);
            response.addBody(test);
        }

        return response;
    }

    private static Message.MessageParameter selectParameter(String line) {
        if ( line.startsWith("Date:") )
            return Message.MessageParameter.DATE;
        else if( line.startsWith("Server:") )
            return Message.MessageParameter.SERVER;
        else if( line.startsWith("Content-Type:") )
            return Message.MessageParameter.CONTENT_TYPE;
        else if( line.startsWith("Content-Length:") )
            return Message.MessageParameter.CONTENT_LENGTH;
        else if( line.startsWith("Last-modified:") )
            return Message.MessageParameter.LAST_MODIFIED;
        else
            return null;
    }

    enum FactoryType {
        PROBLEM,
        RESULT,
        GROUP,
        USER,
        BENCHMARK,
        MANAGEMENT
    }
}
