package edu.northwestern.bioinformatics.studycalendar.restlets;

import edu.northwestern.bioinformatics.studycalendar.StudyCalendarSystemException;
import edu.northwestern.bioinformatics.studycalendar.dao.UserActionDao;
import edu.northwestern.bioinformatics.studycalendar.domain.UserAction;
import gov.nih.nci.logging.api.util.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.Context;
import org.restlet.data.*;
import org.restlet.resource.Representation;
import org.restlet.resource.ResourceException;
import org.restlet.resource.Variant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;

import java.io.IOException;

import static gov.nih.nci.logging.api.util.StringUtils.isBlank;

public class UserActionsResource extends AbstractPscResource {
    protected final Logger log = LoggerFactory.getLogger(getClass());
    private UserActionDao userActionDao;

    @Override
    public void init(Context context, Request request, Response response) {
        super.init(context, request, response);
        setAllAuthorizedFor(Method.POST);
        setReadable(false);
        getVariants().add(new Variant(MediaType.APPLICATION_JSON));
    }

    @Override public boolean allowPost() { return true; }

    @Override
    public void acceptRepresentation(Representation representation) throws ResourceException {
        if (representation.getMediaType().isCompatible(MediaType.APPLICATION_JSON)) {
            UserActionJSONRepresentation json = createJSONRepresentation(representation);

            String errorMessage = json.validate();
            if (errorMessage != null) {
                throw new ResourceException(
                    Status.CLIENT_ERROR_BAD_REQUEST, errorMessage);
            }

            UserAction action = json.createUserAction();

            userActionDao.save(action);

            getResponse().setStatus(Status.SUCCESS_CREATED);
            getResponse().setLocationRef(String.format(
                "user-actions/%s", Reference.encode(action.getGridId())));
        } else {
            throw new ResourceException(
                Status.CLIENT_ERROR_BAD_REQUEST, "Unsupported content type: " + representation.getMediaType());
        }
    }

    private UserActionJSONRepresentation createJSONRepresentation(Representation representation) throws ResourceException {
        try {
            return new UserActionJSONRepresentation(representation.getText());
        } catch (JSONException e) {
            throw new StudyCalendarSystemException("Problem reading JSON", e);
        } catch (IOException e) {
            throw new StudyCalendarSystemException("Problem reading JSON", e);
        }
    }

    private class UserActionJSONRepresentation {
        private JSONObject wrapper;

        private UserActionJSONRepresentation(String json) throws JSONException {
            this.wrapper = new JSONObject(json);
        }

        public UserAction createUserAction() {
            UserAction action = new UserAction();
            try {
                action.setContext(wrapper.getString("context"));
                action.setActionType(wrapper.getString("actionType"));
                action.setDescription(wrapper.getString("description"));
                action.setUser(getCurrentUser().getCsmUser());
            } catch (JSONException e) {
                throw new StudyCalendarSystemException("Problem reading JSON", e);
            }
            return action;
        }

        private String[] REQUIRED_KEYS = {"description", "context", "actionType"};
        public String validate() {
            for (String key : REQUIRED_KEYS) {
                try {
                    if (!wrapper.has(key)) {
                        return "Missing attribute: " + key;
                    } else if (wrapper.isNull(key) || isBlank(wrapper.getString(key))) {
                        return "Blank attribute: " + key;
                    }
                } catch (JSONException e) {
                    return "Missing attribute: " + key;
                }
            }
            return null;
        }
    }

    //    private class UserActionPost {
//        private JSONObject json;
//
//        private UserActionPost(JSONObject json) {
//            this.json = json;
//        }
//
//        public UserAction apply() {
//
//        }
//    }
    
    @Required
    public void setUserActionDao(UserActionDao userActionDao) {
        this.userActionDao = userActionDao;
    }
}

@@ -296,57 +296,8 @@
 ort 
-gov.nih.nci.logging.api.util.StringUtils;%0Aimport 
 org.
@@ -342,16 +342,83 @@
 ONObject
+;%0Aimport org.restlet.data.MediaType;%0Aimport org.restlet.data.Method
 ;%0Aimport
@@ -430,23 +430,30 @@
 restlet.
-Context
+data.Reference
 ;%0Aimport
@@ -474,9 +474,14 @@
 ata.
-*
+Status
 ;%0Aim
@@ -499,24 +499,65 @@
 stlet.re
-source.R
+presentation.Representation;%0Aimport org.restlet.r
 epresent
@@ -553,32 +553,40 @@
 t.representation
+.Variant
 ;%0Aimport org.res
@@ -622,45 +622,8 @@
 on;%0A
-import org.restlet.resource.Variant;%0A
 impo
@@ -1030,76 +1030,55 @@
    p
-ublic
+rotected
  void 
-i
+doI
 nit(
-Context context, Request request, Response response)
+) throws ResourceException
  %7B%0A 
@@ -1094,39 +1094,15 @@
 per.
-i
+doI
 nit(
-context, request, response
 );%0A 
@@ -1146,36 +1146,8 @@
 T);%0A
-        setReadable(false);%0A
     
@@ -1234,90 +1234,23 @@
 ride
- public boolean allowPost() %7B return true; %7D%0A%0A    @Override%0A    public void accept
+%0A    protected 
 Repr
@@ -1251,32 +1251,37 @@
 d Representation
+ post
 (Representation 
@@ -1276,38 +1276,47 @@
 resentation 
-representation
+entity, Variant variant
 ) throws Res
@@ -1344,30 +1344,22 @@
     if (
-representation
+entity
 .getMedi
@@ -1483,30 +1483,22 @@
 ntation(
-representation
+entity
 );%0A%0A    
@@ -2141,30 +2141,22 @@
 pe: %22 + 
-representation
+entity
 .getMedi
@@ -2167,32 +2167,53 @@
 e());%0A        %7D%0A
+        return null;%0A
     %7D%0A%0A    priva
@@ -4091,248 +4091,8 @@
    %7D
-%0A%0A    //    private class UserActionPost %7B%0A//        private JSONObject json;%0A//%0A//        private UserActionPost(JSONObject json) %7B%0A//            this.json = json;%0A//        %7D%0A//%0A//        public UserAction apply() %7B%0A//%0A//        %7D%0A//    %7D
 %0A   

Modify UserActionsResource to work with new restlets framework. Feature #1281.