/*
 *******************************************************************************
 * Copyright (c) 2018 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************
*/

package org.eclipse.openk.resources;


import com.codahale.metrics.annotation.Timed;
import com.google.gson.JsonObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import javassist.bytecode.ByteArray;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.eclipse.openk.api.BackendSettings;
import org.eclipse.openk.api.Calender;
import org.eclipse.openk.api.Document;
import org.eclipse.openk.api.FilterObject;
import org.eclipse.openk.api.GridMeasure;
import org.eclipse.openk.api.HGridMeasure;
import org.eclipse.openk.api.Lock;
import org.eclipse.openk.api.VersionInfo;
import org.eclipse.openk.common.Globals;
import org.eclipse.openk.common.JsonGeneratorBase;
import org.eclipse.openk.common.mapper.generic.GenericApiToDbMapper;
import org.eclipse.openk.core.controller.GridMeasureBackendController;
import org.eclipse.openk.core.controller.ResponseBuilderWrapper;
import org.eclipse.openk.core.controller.TokenManager;
import org.eclipse.openk.core.exceptions.HttpStatusException;
import org.eclipse.openk.core.exceptions.PgmExceptionMapper;
import org.eclipse.openk.db.model.TblDocuments;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.NotSupportedException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import static org.eclipse.openk.api.BackendSettings.BpmnGridConfig.END_AFTER_APPROVED;
import static org.eclipse.openk.api.BackendSettings.BpmnGridConfig.END_AFTER_RELEASED;
import static org.eclipse.openk.api.BackendSettings.BpmnGridConfig.SKIP_FOR_APPROVAL;
import static org.eclipse.openk.api.BackendSettings.BpmnGridConfig.SKIP_IN_WORK;
import static org.eclipse.openk.api.BackendSettings.BpmnGridConfig.SKIP_REQUESTING;

@Api(value = "/mics/gridmeasures")
@ApiResponses( value ={
        @ApiResponse(code = 200, message = "OK",response = VersionInfo.class,reference = "#/definitions/VersionInfo"),
        @ApiResponse(code = 400, message = "Bad Request"),
        @ApiResponse(code = 401, message = "Unauthorized"),
        @ApiResponse(code = 404, message = "Not found"),
        @ApiResponse(code = 423, message = "Locked"),
        @ApiResponse(code = 500, message = "Internal Server Error") } )
@Path("/mics/gridmeasures")
public class PlannedGridMeasuresResource extends BaseResource {
    private static final Logger LOGGER = Logger.getLogger(PlannedGridMeasuresResource.class.getName());

    public PlannedGridMeasuresResource() {
        super(LOGGER);

    }

    @ApiOperation(value = "Version Information", notes = "This services displays the version infos of this backend and the connected database.")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = VersionInfo.class,reference = "#/definitions/VersionInfo") } )
    @GET
    @Path("/versionInfo")
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getVersionInfo() {
        return invokeRunnable(null, SecureType.NONE, modusr -> new GridMeasureBackendController().getVersionInfo(getVersionString()));
    }


    @ApiOperation(value = "Store planned grid measure", notes = "This services stores the given grid measure in the "+
                                                                "database and resumes the bpmn-process.")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = GridMeasure.class,reference = "#/definitions/GridMeasure") } )
    @PUT
    @Path("/storeGridMeasure")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response storeGridMeasure(@ApiParam(name="Authorization", value="JWT Token", required=true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt,
                                     @ApiParam(name="Payload", value="GridMeasure to store", required=true, example = "see GridMeasure below") String gridMeasure) {

        GridMeasure gridMeasureObj = JsonGeneratorBase.getGson().fromJson(gridMeasure, GridMeasure.class);
        return invokeRunnable(jwt, SecureType.NORMAL, (String modusr) ->  new GridMeasureBackendController()
                    .storeGridMeasure(jwt, modusr, gridMeasureObj)
        );
    }


    @ApiOperation(value = "Get grid measures", notes = "This service gets all grid measures from the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = GridMeasure.class,reference = "#/definitions/GridMeasure") } )
    @POST
    @Path("/getGridMeasures")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getGridMeasures(@ApiParam(name ="Authorization", value ="JWT Token", required =true)
                                    @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt,
                                    @ApiParam(name="filterObject", value="object to filter grid measure for status", required=true)
                                    String filterObject) {

        FilterObject filterObjectPro = JsonGeneratorBase.getGson().fromJson(filterObject, FilterObject.class);
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getGridMeasures(modusr, filterObjectPro));
    }

    @ApiOperation(value = "Get grid measure", notes = "This service retrieves a grid measure from the database using the id and a filter-object")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = GridMeasure.class,reference = "#/definitions/GridMeasure") } )
    @GET
    @Path("/getGridMeasure/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getGridMeasure(@ApiParam(name ="Authorization", value ="JWT Token", required =true)
                                   @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt,
                                   @ApiParam(name ="id", value ="id", required =true)
                                   @PathParam("id") String id) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getGridMeasureById(Integer.parseInt(id)));
    }

    @ApiOperation(value = "Get Calender", notes = "This service gets single gridmeasures for the calender view")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = Calender.class,reference = "#/definitions/Calender") } )
    @GET
    @Path("/getCalender")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getCalender(@ApiParam(name ="Authorization", value ="JWT Token", required =true)
                                    @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getCalender());
    }


    @ApiOperation(value = "Get Current Reminders", notes = "This service retrieves a list of Gridmeasure-Ids")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = GridMeasure.class,reference = "#/definitions/GridMeasure") } )
    @GET
    @Path("/getCurrentReminders")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getCurrentReminders(@ApiParam(name ="Authorization", value ="JWT Token", required =true)
                                        @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getCurrentReminders(jwt));
    }

    @ApiOperation(value = "Get Expired Reminders", notes = "This service retrieves a list of Gridmeasure-Ids")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = GridMeasure.class,reference = "#/definitions/GridMeasure") } )
    @GET
    @Path("/getExpiredReminders")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getExpiredReminders(@ApiParam(name ="Authorization", value ="JWT Token", required =true)
                                        @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getExpiredReminders(jwt));
    }


    @ApiOperation(value = "Upload a grid measure document", notes = "This service uploads and stores a document in the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = Document.class,reference = "#/definitions/Document") } )
    @POST
    @Path("/uploadGridMeasureAttachments/{gridmeasuereId}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response uploadGridMeasureAttachments(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt,
        @PathParam("gridmeasuereId") String gridmeasuereId, String document
    ) {

        Document documentObj = JsonGeneratorBase.getGson().fromJson(document, Document.class);
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
            .uploadDocument(documentObj, modusr, Integer.parseInt(gridmeasuereId)));
    }

    @ApiOperation(value = "Get Attachments List", notes = "This service gets all attachments for the given gridmeasure from the Database")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = Document.class, reference = "#/definitions/Document")})
    @GET
    @Path("/getGridMeasureAttachments/{gridmeasuereId}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getGridMeasureAttachments(@PathParam("gridmeasuereId") String id,
        @ApiParam(name = "Authorization", value = "JWT Token", required = true) @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL,
            modusr -> new GridMeasureBackendController().getGridMeasureAttachments(Integer.valueOf(id)));
    }

    @ApiOperation(value = "Download attachment", notes = "This service downloads the selected attachment for the given gridmeasure from the Database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = ByteArray.class) } )
    @GET
    @Path("/downloadGridMeasureAttachment/{documentId}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response downloadGridMeasureAttachment(@PathParam("documentId") String id,
        @ApiParam(name = "Authorization", value = "JWT Token", required = true) @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {

        try {
            assertAndRefreshToken(jwt, SecureType.NORMAL);
            TblDocuments tblDocuments = new GridMeasureBackendController().downloadGridMeasureAttachment(Integer.parseInt(id));
            String base64String = Base64.encodeBase64String(tblDocuments.getDocument());
            GenericApiToDbMapper mapper = new GenericApiToDbMapper();
            Document document = mapper.mapToViewModel(Document.class, tblDocuments);
            document.setData(base64String);

            return Response.ok(JsonGeneratorBase.getGson().toJson(document)).build();

        } catch (Exception e) {
            return responseFromException(e);
        }
    }


    @ApiOperation(value = "Delete attachment", notes = "This service deletes the selected attachment for the given gridmeasure from the Database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = Response.class) } )
    @DELETE
    @Path("/deleteGridMeasureAttachment/{documentId}")
    @Timed
    public Response deleteGridMeasureAttachment(@PathParam("documentId") String id,
        @ApiParam(name = "Authorization", value = "JWT Token", required = true) @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL,
            modusr -> new GridMeasureBackendController().deleteDocument(modusr, Integer.parseInt(id)));
    }


    @ApiOperation(value = "Get historical grid measures status changes", notes = "This service gets all status changes for a grid measure from the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = HGridMeasure.class,reference = "#/definitions/HGridMeasure") } )
    @GET
    @Path("/getHistoricalStatusChanges/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getHistoricalStatusChanges(@ApiParam(name ="Authorization", value ="JWT Token", required =true)
                                   @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt,
                                   @ApiParam(name ="id", value ="id", required =true)
                                   @PathParam("id") String id) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getHistoricalStatusChangesById(Integer.parseInt(id)));
    }

    @ApiOperation(value = "AffectedResources", notes = "This service gets all possible Affected Resources from the Database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = String.class,reference = "#/definitions/GridMeasure.affectedResource") } )
    @GET
    @Path("/getAffectedResourcesDistinct")
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getAffectedResources(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getAffectedResourcesDistinct());
    }

    @ApiOperation(value = "GetMailAddressesFromGridmeasures", notes = "This service retrieves all mail-addresses from Gridmeasures in the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = String.class,reference = "#/definitions/GridMeasure.affectedResource") } )
    @GET
    @Path("/getMailAddressesFromGridmeasures")
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getMailAddressesFromGridmeasures(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getMailAddressesFromGridmeasures());
    }


    @ApiOperation(value = "Logout", notes = "This services kills the server session belonging to the the given session token.")
    @GET
    @Path("/logout")
    @Produces("application/json")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK") } )
    public Response logout(@ApiParam( name = "Authorization", value = "JWT Token", required = true)
                           @HeaderParam(value = Globals.KEYCLOAK_AUTH_TAG) String token) {

        try (AutoCloseable ignored = perform("logout()")) { // NOSONAR
            TokenManager.getInstance().logout(token);
            return ResponseBuilderWrapper.INSTANCE.buildOKResponse(PgmExceptionMapper.getGeneralOKJson());
        } catch (Exception e) {
            return responseFromException(e);
        }
    }

    @ApiOperation(value = "Check Lock", notes = "This service checks if there is already a Lock for the given key and the given info within the JSON.")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = Lock.class, reference = "#/definitions/Lock") } )
    @GET
    @Path("/checkLock/{key}/{info}")
    //@Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response checkLock(@PathParam("key") String key, @PathParam("info") String info, @ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .checkLock(Integer.parseInt(key), info));
    }

    @ApiOperation(value = "Create Lock", notes = "This service creates or updates a Lock for the given User and the given Gridmeasure-Id.")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = Lock.class, reference = "#/definitions/Lock") } )
    @PUT
    @Path("/createLock")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response createLock(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt,
                               String lockString) {
        Lock lock = JsonGeneratorBase.getGson().fromJson(lockString, Lock.class);
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .createLock(modusr, lock.getKey(), lock.getInfo()));
    }

    @ApiOperation(value = "Delete Lock", notes = "This service deletes the lock for the given key and info. Use force="
            +Globals.FORCE_DELETE_LOCK+" to enforce the deletion of the lock.")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK",  response = Response.class) } )
    @DELETE
    @Path("/deleteLock/{key}/{info}/{force}")
    @Timed
    public Response deleteLock(@PathParam("key") String key, @PathParam("info") String info,
                               @PathParam("force") String force,
                               @ApiParam(name = "Authorization", value = "JWT Token", required = true)
                               @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        boolean isForce = force.equalsIgnoreCase(Globals.FORCE_DELETE_LOCK);
        try {
            if( isForce ) {
                TokenManager.getInstance().checkAutLevel(jwt, SecureType.HIGH);
            }
        } catch (HttpStatusException e) {
            responseFromException(e);
        }


        return invokeRunnable(jwt, SecureType.NORMAL,
                modusr -> new GridMeasureBackendController().deleteLock(modusr, Integer.parseInt(key), info, isForce));
    }

    @ApiOperation(value = "Get Role Access Definition", notes = "This service gets a Json-file which defines access to GridMeasures for each role")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = JsonObject.class)})
    @GET
    @Path("/getRoleAccessDefinition")
    //@Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getRoleAccessDefinition(@ApiParam(name = "Authorization", value = "JWT Token", required = true)
                                            @HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL,
                modusr -> new GridMeasureBackendController().recalcAndGetRoleAccessDefinition());
    }


    @ApiOperation(value = "Grid configuration", notes = "This service modifies the backend grid configuration for test "+
            "puposes. The method will not be available within a release build!")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = BackendSettings.BpmnGridConfig.class,reference = "#/definitions/BackendSettings.BpmnGridConfig") } )
    @GET
    @Path("/setGridConfig")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response storeBackendConfig(@ApiParam(name = SKIP_FOR_APPROVAL, value = "Configuration switch", required = false) @QueryParam(SKIP_FOR_APPROVAL) Boolean isSkipForApproval,
                                       @ApiParam(name = END_AFTER_APPROVED, value = "Configuration switch", required = false) @QueryParam(END_AFTER_APPROVED) Boolean isEndAfterApproved,
                                       @ApiParam(name = SKIP_REQUESTING, value = "Configuration switch", required = false) @QueryParam(SKIP_REQUESTING) Boolean isSkipRequesting,
                                       @ApiParam(name = END_AFTER_RELEASED, value = "Configuration switch", required = false) @QueryParam(END_AFTER_RELEASED) Boolean isEndAfterReleased,
                                       @ApiParam(name = SKIP_IN_WORK, value = "Configuration switch", required = false) @QueryParam(SKIP_IN_WORK) Boolean isSkipInWork) {

        if( !isDevelopMode() ) {
            // Only allowed in DEVELOP-VERSION
            throw new NotSupportedException();
        }
        return invokeRunnable(null, SecureType.NONE, modusr -> new GridMeasureBackendController()
                .setGridConfig(isSkipForApproval, isEndAfterApproved, isSkipRequesting, isEndAfterReleased, isSkipInWork));
    }


    @ApiOperation(value = "responsibles on-site", notes = "This service retrieves all responsibles on-site from single gridmeasures in the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = String.class,reference = "#/definitions/GridMeasure.responsibleOnSiteName") } )
    @GET
    @Path("/getResponsiblesOnSiteFromSingleGridmeasures")
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getResponsiblesOnSiteFromSingleGridmeasures(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getResponsiblesOnSiteFromSingleGridmeasures());
    }


    @ApiOperation(value = "network controls", notes = "This service retrieves all network controls as Strings from the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = String.class,reference = "#/definitions/SingleGridmeasure.networkControl") } )
    @GET
    @Path("/getNetworkControlsFromSingleGridmeasures")
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getNetworkControlsFromSingleGridmeasures(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getNetworkControlsFromSingleGridmeasures());
    }

    @ApiOperation(value = "user departments", notes = "This service gets all known User-Departments for the field responsible_onsite_department as Strings from the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = String.class) } )
    @GET
    @Path("/getUserDepartmentsResponsibleOnSite")
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getUserDepartmentsResponsibleOnSite(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getUserDepartmentsResponsibleOnSite());
    }

    @ApiOperation(value = "user departments", notes = "This service gets all known User-Departments for the field create_user_department as Strings from the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = String.class) } )
    @GET
    @Path("/getUserDepartmentsCreated")
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getUserDepartmentsCreated(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getUserDepartmentsCreated());
    }

    @ApiOperation(value = "user departments", notes = "This service gets all known User-Departments for the field mod_user_department as Strings from the database")
    @ApiResponses( value ={ @ApiResponse(code = 200, message = "OK", response = String.class) } )
    @GET
    @Path("/getUserDepartmentsModified")
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public Response getUserDepartmentsModified(@ApiParam(name ="Authorization", value ="JWT Token", required =true)@HeaderParam(Globals.KEYCLOAK_AUTH_TAG) String jwt) {
        return invokeRunnable(jwt, SecureType.NORMAL, modusr -> new GridMeasureBackendController()
                .getUserDepartmentsModified());
    }


    private Response responseFromException(Exception e) {
        int errcode;
        String retJson;

        if (e instanceof HttpStatusException) {
            LOGGER.error("Caught BackendException", e);
            errcode = ((HttpStatusException) e).getHttpStatus();
            retJson = PgmExceptionMapper.toJson((HttpStatusException) e);
            return Response.status(errcode).entity(retJson).build();
        } else {
            LOGGER.error("Unexpected exception", e);
            return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
                    .entity(PgmExceptionMapper.getGeneralErrorJson()).build();
        }
    }

}
