/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package reseau;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Dream Team
 */
final class Message {

    // Declaration de variables
    private Map<Class, String> header = new HashMap<Class, String>();
    private Map<MessageParameter, String> parameters = new HashMap<MessageParameter, String>();
    private StringBuilder content = new StringBuilder();

    private boolean built = false;

    private String messageValue;

    public Message() {
    }

    public void setMessageAction(String messageAction) {
        header.put(MessageAction.class, messageAction);
        built = false;
    }

    String getMessageAction() {
        return header.get(MessageAction.class);
    }

    public void setMessageURL(String messageSubject) {
        header.put(URL.class, messageSubject);
        built = false;
    }

    String getMessageURL() {
        return header.get(URL.class);
    }

    public void addParameter(MessageParameter parameter, String value) {
        parameters.put(parameter, value);
        built = false;
    }

    public void addBody(String bodyContent) {
        content.append(bodyContent);
        built = false;
    }

    public String getBody() {
        return content.toString().trim();
    }

    public String extract(MessageParameter parameter) {
        return parameters.get(parameter);
    }

    @Override
    public String toString() {
        if (!built)
            build();
        return messageValue;
    }

    private void build() {
        StringBuilder sb = new StringBuilder();

        //Step 0 : parsing URL
        String url = header.get(URL.class);

        url = url.replaceAll("\\{groupId\\}", parameters.get(MessageParameter.CURRENT_GROUP_ID));
        url = url.replaceAll("\\{targetId\\}", parameters.get(MessageParameter.TARGET_ID));

        if (!parameters.isEmpty()) {
            url += "?";
            if (parameters.containsKey(MessageParameter.CURRENT_USER_ID))
                url += checkBeginning(url) + "userid=" + parameters.get(MessageParameter.CURRENT_USER_ID);
            if (parameters.containsKey(MessageParameter.CURRENT_GROUP_ID))
                url += checkBeginning(url) + "groupid=" + parameters.get(MessageParameter.CURRENT_GROUP_ID);
            if (parameters.containsKey(MessageParameter.LOGIN))
                url += checkBeginning(url) + "login=" + parameters.get(MessageParameter.LOGIN);
            if (parameters.containsKey(MessageParameter.PASSWORD))
                url += checkBeginning(url) + "password=" + parameters.get(MessageParameter.PASSWORD);
            if (parameters.containsKey(MessageParameter.PROBLEM_ID))
                url += checkBeginning(url) + "problemid=" + parameters.get(MessageParameter.PROBLEM_ID);
            if (parameters.containsKey(MessageParameter.METHOD_ID))
                url += checkBeginning(url) + "methodid=" + parameters.get(MessageParameter.METHOD_ID);
            if (parameters.containsKey(MessageParameter.METHOD_IDS)) {
                int methodNumber = parameters.get(MessageParameter.METHOD_IDS).split(",").length;
                url += checkBeginning(url) + "methodnumber=" + String.valueOf(methodNumber) + "&methodids=" + parameters.get(MessageParameter.METHOD_IDS);
            }
        }

        // Step 1 : Building header
        sb.append(header.get(MessageAction.class) + " " + url + " " + "HTTP/1.1\n");

        // Step 2 : Adding Metadatas
        sb.append("Host: www.optim-eisti.com\n");
        sb.append("User-Agent: Mon-putain-de-client-Java/1.0\n");
        sb.append("\n");

        // Step 4 : Adding body
        sb.append(content.toString());

        // Step 5 : Message end
        sb.append("\n");

        messageValue = sb.toString();

        built = true;
    }

    private String checkBeginning(String url) {
        return ( url.endsWith("?") )? "" : "&";
    }

    public enum MessageAction {
        CREATE,
        READ,
        UPDATE,
        DELETE,
        AUTHENTICATION,
        FETCH_GROUPS,
        FETCH_USERS,
        FETCH_PROBLEMS,
        FETCH_RESULTS,
        FETCH_BENCHMARKS,
        SEND_FILES
    }

    public enum MessageParameter {
        //Request parameter
        CURRENT_USER_ID,
        CURRENT_GROUP_ID,
        TARGET_ID,
        PROBLEM_ID,
        METHOD_ID,
        METHOD_IDS,
        UPLOAD_FILES,
        LOGIN,
        PASSWORD,
        //Response parameter
        STATUS_CODE,DATE, SERVER, CONTENT_TYPE, CONTENT_LENGTH, LAST_MODIFIED, ID
    }

}
