package org.dainst.chronontology.handler;

import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.RandomStringUtils;
import org.dainst.chronontology.handler.dispatch.Dispatcher;
import org.dainst.chronontology.handler.model.Document;
import org.dainst.chronontology.handler.model.RightsValidator;
import spark.Request;
import spark.Response;

import java.io.IOException;

import static org.dainst.chronontology.Constants.HTTP_BAD_REQUEST;
import static org.dainst.chronontology.Constants.HTTP_FORBIDDEN;
import static org.dainst.chronontology.util.JsonUtils.json;

/**
 * @author Daniel de Oliveira
 */
public abstract class DocumentHandler implements Handler {

    private static final String ID = ":id";

    public DocumentHandler(Dispatcher dispatcher, RightsValidator rightsValidator) {
        this.dispatcher = dispatcher;
        this.rightsValidator= rightsValidator;
    }

    protected final Dispatcher dispatcher;
    protected final RightsValidator rightsValidator;


    protected final Document makeDocumentModel(
            Request req,
            Response res,
            boolean createId) {

        JsonNode n= json(req.body());
        if (n==null) {
            res.status(HTTP_BAD_REQUEST);
            return null;
        }

        String resourceId= null;
        String resourceType= null;

        if (createId) {
            resourceId= determineFreeId(req);
            resourceType= req.pathInfo().replaceAll("/","");
        } else {
            resourceId= req.pathInfo().replaceFirst("\\/.*\\/","");
            resourceType= req.pathInfo().substring(0,req.pathInfo().lastIndexOf("/")).replaceAll("/","");
        }

        Document dm = new Document(
                resourceId, resourceType,json(req.body()), req.attribute("user"));

        if (!userAccessLevelSufficient(req,dm, RightsValidator.Operation.EDIT)) {
            res.status(HTTP_FORBIDDEN);
            return null;
        }
        return dm;
    }

    protected final boolean userAccessLevelSufficient(Request req, Document dm, RightsValidator.Operation operation) {
        if (dm.getDataset()!=null &&
                !rightsValidator.hasPermission(req.attribute("user"),
                        dm.getDataset(), operation)) {
            return false;
        }
        return true;
    }

    protected String type(Request req) {
        String tmp = req.pathInfo();
        if (tmp.startsWith("/data/")) tmp = tmp.substring(6);
        if (req.params(ID) != null) tmp = tmp.replace(req.params(ID),"");
        return tmp;
    }

    protected String simpleId(Request req) {
        return req.params(ID);
    }

    private static String generateId() {
        return RandomStringUtils.randomAlphanumeric(12);
    }

    private String determineFreeId(Request req) {
        String id;
        JsonNode existingDoc= null;
        do {
            id= generateId();
            existingDoc = dispatcher.dispatchGet(req.pathInfo(),id);
        } while (existingDoc!=null);
        return id;
    }

    @Override
    public abstract Object handle(Request req, Response res) throws IOException;
}

@@ -1341,16 +1341,170 @@
  null;%0D%0D
+        String pathInfo= req.pathInfo();%0D        if (req.pathInfo().startsWith(%22/data/%22)) %7B%0D            pathInfo= req.pathInfo().substring(5);%0D        %7D%0D%0D
         
@@ -1591,28 +1591,24 @@
 ceType= 
-req.
 pathInfo
 ().repla
@@ -1591,34 +1591,32 @@
 ceType= pathInfo
-()
 .replaceAll(%22/%22,
@@ -1661,28 +1661,24 @@
 urceId= 
-req.
 pathInfo
 ().repla
@@ -1669,18 +1669,16 @@
 pathInfo
-()
 .replace
@@ -1725,28 +1725,24 @@
 ceType= 
-req.
 pathInfo
 ().subst
@@ -1725,34 +1725,32 @@
 ceType= pathInfo
-()
 .substring(0,req
@@ -1746,28 +1746,24 @@
 tring(0,
-req.
 pathInfo
 ().lastI
@@ -1754,18 +1754,16 @@
 pathInfo
-()
 .lastInd

Fix wrong type generation when spasupport activated.