package net.qldarch.archobj;

import java.util.Map;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import org.apache.commons.lang3.StringUtils;

import net.qldarch.hibernate.HS;
import net.qldarch.jaxrs.ContentType;
import net.qldarch.security.UpdateEntity;
import net.qldarch.security.User;
import net.qldarch.util.M;
import net.qldarch.util.ObjUtils;
import net.qldarch.util.UpdateUtils;

@Path("/archobj")
public class WsUpdateArchObj {

  @Inject
  private HS hs;

  @Inject @Nullable
  private User user;

  @POST
  @Path("/{id}")
  @Consumes("application/x-www-form-urlencoded")
  @Produces(ContentType.JSON)
  @UpdateEntity(entityClass=ArchObj.class)
  public Response post(@PathParam("id") Long id, MultivaluedMap<String, Object> params) {
    return hs.execute(session -> {
      final ArchObj archobj = hs.get(ArchObj.class, id);
      final Map<String, Object> m = UpdateUtils.asMap(params);
      final String comment = ObjUtils.asString(m.get("comment"));
      if(archobj != null) {
        final Long reqVersion = ObjUtils.asLong(m.get("version"));
        if((reqVersion != null) && !reqVersion.equals(archobj.getVersion()) && (archobj.getVersion() != null)) {
          ArchObjVersion version = hs.get(ArchObjVersion.class, reqVersion);
          if((version != null) && version.getOid().equals(archobj.getId())) {
            archobj.copyFrom(version.getDocumentAsMap());
            archobj.setVersion(version.getId());
            if(archobj.updateFrom(m)) {
              final String revertComment = String.format("reverting to version '%s' before change",
                  version.getId());
              final String newComment = StringUtils.isBlank(comment)?revertComment:
                String.format("%s (%s)", comment, revertComment);
              VersionUtils.createNewVersion(hs, user, archobj, newComment);
              hs.update(archobj);
            } else {
              throw new RuntimeException("no change detected, rollback revert to ealier version");
            }
            return Response.ok().entity(archobj).build();
          } else {
            return Response.status(404).entity(M.of("msg","version not found")).build();
          }
        } else {
          // create an initial version in the version history if it does not exist yet
          if(archobj.getVersion() == null) {
            VersionUtils.createNewVersion(hs, user, archobj, "initial version");
            hs.update(archobj);
          }
          if(archobj.updateFrom(m)) {
            VersionUtils.createNewVersion(hs, user, archobj, comment);
            hs.update(archobj);
          }
        }
        return Response.ok().entity(archobj).build();
      } else {
        return Response.status(404).build();
      }
    });
  }

}

@@ -390,20 +390,275 @@
 rch.
-hibernate.HS
+gson.JsonSkipField;%0Aimport net.qldarch.gson.serialize.CollectionRemoveNullsSerializer;%0Aimport net.qldarch.gson.serialize.JsonSerializer;%0Aimport net.qldarch.hibernate.HS;%0Aimport net.qldarch.interview.InterviewUtteranceSerializer;%0Aimport net.qldarch.interview.Utterance
 ;%0Aim
@@ -693,16 +693,48 @@
 ntType;%0A
+import net.qldarch.media.Media;%0A
 import n
@@ -1124,16 +1124,16 @@
 e.JSON)%0A
-
   @Updat
@@ -1167,16 +1167,654 @@
 .class)%0A
+  @JsonSkipField(type=Media.class, field=%22depicts%22)%0A  @JsonSerializer(type=Utterance.class, serializer=InterviewUtteranceSerializer.class)%0A  @JsonSerializer(path=%22$.precededby%22, serializer=SimpleArchObjSerializer.class)%0A  @JsonSerializer(path=%22$.succeededby%22, serializer=SimpleArchObjSerializer.class)%0A  @JsonSerializer(path=%22$.interviews%22, serializer=CollectionRemoveNullsSerializer.class)%0A  @JsonSerializer(path=%22$.interviews.*%22, serializer=IdArchObjSerializer.class)%0A  @JsonSerializer(path=%22$.interviewer.*%22, serializer=SimpleArchObjSerializer.class)%0A  @JsonSerializer(path=%22$.interviewee.*%22, serializer=SimpleArchObjSerializer.class)%0A
   public

add custom json serializers to the update archive object service