package fi.nls.oskari.control.admin;

import static fi.nls.oskari.control.ActionConstants.KEY_ID;
import static fi.nls.oskari.control.ActionConstants.KEY_NAME;

import java.util.LinkedHashSet;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.oskari.permissions.PermissionService;
import org.oskari.permissions.model.PermissionType;

import fi.nls.oskari.annotation.OskariActionRoute;
import fi.nls.oskari.control.ActionException;
import fi.nls.oskari.control.ActionParameters;
import fi.nls.oskari.control.RestActionHandler;
import fi.nls.oskari.domain.Role;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
import fi.nls.oskari.service.OskariComponentManager;
import fi.nls.oskari.service.ServiceException;
import fi.nls.oskari.service.UserService;
import fi.nls.oskari.util.JSONHelper;
import fi.nls.oskari.util.ResponseHelper;

@OskariActionRoute("GetAllRolesAndPermissionTypes")
public class GetAllRolesAndPermissionTypesHandler extends RestActionHandler {
    
    private Logger log = LogFactory.getLogger(GetAllRolesAndPermissionTypesHandler.class);
    private UserService userService = null;
    private PermissionService permissionsService = null;

    private final static String JSKEY_ID = "id";
    private final static String JSKEY_NAME = "name";
    private final static String JSKEY_ROLES = "roles";
    private final static String JSKEY_PERMISSION_TYPES = "permissionTypes";

    @Override
    public void init() {
        try {
            userService = UserService.getInstance();
        } catch (ServiceException ex) {
            log.error(ex, "Unable to initialize User service!");
            throw new RuntimeException(ex);
        }
        
        try {
            permissionsService = OskariComponentManager.getComponentOfType(PermissionService.class);
        } catch (Exception ex) {
            log.error(ex, "Unable to initialize permission service!");
            throw new RuntimeException(ex);
        }
    }

    @Override
    public void preProcess(ActionParameters params) throws ActionException {
        params.requireAdminUser();
    }

    @Override
    public void handleGet(ActionParameters params) throws ActionException {
        try {
            final JSONObject root = new JSONObject();
            JSONHelper.putValue(root, JSKEY_ROLES, getRoles());
            JSONHelper.putValue(root, JSKEY_PERMISSION_TYPES, getPermissionTypes(params.getLocale().getLanguage()));
            ResponseHelper.writeResponse(params, root);
        } catch (Exception e) {
            throw new ActionException("Something went wrong getting roles and permission types from the platform", e);
        }
    }

    private JSONArray getRoles() throws ServiceException, JSONException  {
        final Role[] roles = userService.getRoles();
        final JSONArray rolesJSON = new JSONArray();

        for (Role role : roles) {
            JSONObject external = new JSONObject();
            external.put(JSKEY_ID, role.getId());
            external.put(JSKEY_NAME, role.getName());
            rolesJSON.put(external);
        }
        return rolesJSON;
    }  
    
    private JSONArray getPermissionTypes(String language) {
        
        final JSONArray permissionNames = new JSONArray();
        for (String id : getAvailablePermissions()) {
            JSONObject perm = new JSONObject();
            JSONHelper.putValue(perm, KEY_ID, id);
            JSONHelper.putValue(perm, KEY_NAME, permissionsService.getPermissionName(id, language));
            permissionNames.put(perm);
        }
       return permissionNames;
    }
    
    private Set<String> getAvailablePermissions() {
        
        Set<String> availablePermissionTypes = new LinkedHashSet <>();
        for (PermissionType type : PermissionType.values()) {
            if (type.isLayerSpecific()) {
                availablePermissionTypes.add(type.name());
            }
        }
        // add any additional permissions
        availablePermissionTypes.addAll(permissionsService.getAdditionalPermissions());
        return availablePermissionTypes;
    }
}

@@ -627,78 +627,8 @@
 le;%0A
-import fi.nls.oskari.log.LogFactory;%0Aimport fi.nls.oskari.log.Logger;%0A
 impo
@@ -715,32 +715,86 @@
 rviceException;%0A
+import fi.nls.oskari.service.ServiceRuntimeException;%0A
 import fi.nls.os
@@ -1039,99 +1039,8 @@
    %0A
-    private Logger log = LogFactory.getLogger(GetAllRolesAndPermissionTypesHandler.class);%0A
     
@@ -1533,32 +1533,66 @@
     
-log.error(ex, %22Unable to
+throw new ServiceRuntimeException(%22Exception occured while
  ini
@@ -1597,19 +1597,21 @@
 nitializ
-e U
+ing u
 ser serv
@@ -1617,52 +1617,10 @@
 vice
-!%22);%0A            throw new RuntimeException(
+%22,
 ex);
@@ -1803,32 +1803,66 @@
     
-log.error(ex, %22Unable to
+throw new ServiceRuntimeException(%22Exception occured while
  ini
@@ -1867,17 +1867,19 @@
 nitializ
-e
+ing
  permiss
@@ -1893,52 +1893,10 @@
 vice
-!%22);%0A            throw new RuntimeException(
+%22,
 ex);

Remove logging and use oskari ServiceRuntimeException instead of generic RuntimeException