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.ActionParamsException;
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 (Exception ex) {
            log.error(ex, "Unable to initialize User service!");
        }
        try {
            permissionsService = OskariComponentManager.getComponentOfType(PermissionService.class);
        } catch (Exception ex) {
            log.error(ex, "Unable to initialize permission service!");
        }
    }

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

        if (userService == null) {
            throw new ActionParamsException("User service not initialized");
        }
        if (permissionsService == null) {
            throw new ActionParamsException("PermissionsService service not initialized");
        }
    }

    @Override
    public void handleGet(ActionParameters params) throws ActionException {
        try {
            
            final JSONObject root = new JSONObject();
            getRoles(root);
            getPermissionTypes(root,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 void getRoles(final JSONObject root) 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);
        }

        
        root.put(JSKEY_ROLES, rolesJSON);
    }  
    
    private void getPermissionTypes(JSONObject root, 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);
        }
        JSONHelper.putValue(root, JSKEY_PERMISSION_TYPES, 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;
    }
}

@@ -545,60 +545,8 @@
 rs;%0A
-import fi.nls.oskari.control.ActionParamsException;%0A
 impo
@@ -1593,32 +1593,39 @@
        %7D catch (
+Service
 Exception ex) %7B%0A
@@ -1681,32 +1681,76 @@
 ser service!%22);%0A
+            throw new RuntimeException(ex);%0A
         %7D%0A      
@@ -1735,32 +1735,41 @@
 (ex);%0A        %7D%0A
+        %0A
         try %7B%0A  
@@ -1963,32 +1963,76 @@
 ion service!%22);%0A
+            throw new RuntimeException(ex);%0A
         %7D%0A    %7D%0A
@@ -2161,274 +2161,8 @@
 r();
-%0A%0A        if (userService == null) %7B%0A            throw new ActionParamsException(%22User service not initialized%22);%0A        %7D%0A        if (permissionsService == null) %7B%0A            throw new ActionParamsException(%22PermissionsService service not initialized%22);%0A        %7D
 %0A   
@@ -2273,21 +2273,8 @@
 y %7B%0A
-            %0A
     
@@ -2339,35 +2339,121 @@
     
-getRoles(root);%0A           
+JSONHelper.putValue(root, JSKEY_ROLES, getRoles());%0A            JSONHelper.putValue(root, JSKEY_PERMISSION_TYPES,
  get
@@ -2468,21 +2468,16 @@
 onTypes(
-root,
 params.g
@@ -2497,24 +2497,25 @@
 tLanguage())
+)
 ;%0A          
@@ -2736,28 +2736,33 @@
     private 
-void
+JSONArray
  getRoles(fi
@@ -2759,37 +2759,16 @@
 etRoles(
-final JSONObject root
 ) throws
@@ -2852,25 +2852,24 @@
 getRoles();%0A
-%0A
         fina
@@ -3151,47 +3151,22 @@
   %7D%0A
-%0A        %0A        root.put(JSKEY_ROLES,
+        return
  rol
@@ -3171,17 +3171,16 @@
 olesJSON
-)
 ;%0A    %7D 
@@ -3198,20 +3198,25 @@
 private 
-void
+JSONArray
  getPerm
@@ -3231,25 +3231,8 @@
 pes(
-JSONObject root, 
 Stri
@@ -3628,58 +3628,14 @@
     
- JSONHelper.putValue(root, JSKEY_PERMISSION_TYPES,
+return
  per
@@ -3646,27 +3646,17 @@
 ionNames
-);%0A        
+;
 %0A    %7D%0A 

Fix exception handling in service initialization and change json response construction