/**
   * @param applicationOperationAction holds the information needs to perform an action on mdm.
   * @throws MobileApplicationException
   */
  public String performAction(ApplicationOperationAction applicationOperationAction)
      throws MobileApplicationException {
    if (log.isDebugEnabled()) {
      log.debug(
          applicationOperationAction.getAction()
              + " action is triggered for "
              + applicationOperationAction.getType()
              + ".");
    }

    Operation operation = null;
    List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
    List<org.wso2.carbon.device.mgt.common.Device> deviceList;
    if (MDMAppConstants.USER.equals(applicationOperationAction.getType())) {
      String userName = null;
      try {
        for (String param : applicationOperationAction.getParams()) {
          userName = param;

          deviceList =
              MDMServiceAPIUtils.getDeviceManagementService(
                      applicationOperationAction.getTenantId())
                  .getDevicesOfUser(userName);

          for (org.wso2.carbon.device.mgt.common.Device device : deviceList) {
            deviceIdentifiers.add(getDeviceIdentifierByDevice(device));
          }
        }
      } catch (DeviceManagementException devEx) {
        String errorMsg =
            "Error occurred fetch device for user " + userName + " at app installation";
        logError(errorMsg, devEx);
        throw new MobileApplicationException(errorMsg, devEx);
      }
    } else if (MDMAppConstants.ROLE.equals(applicationOperationAction.getType())) {
      String userRole = null;
      try {
        for (String param : applicationOperationAction.getParams()) {
          userRole = param;

          deviceList =
              MDMServiceAPIUtils.getDeviceManagementService(
                      applicationOperationAction.getTenantId())
                  .getAllDevicesOfRole(userRole);

          for (org.wso2.carbon.device.mgt.common.Device device : deviceList) {
            deviceIdentifiers.add(getDeviceIdentifierByDevice(device));
          }
        }
      } catch (DeviceManagementException devMgtEx) {
        String errorMsg =
            "Error occurred fetch device for user role " + userRole + " at app installation";
        logError(errorMsg, devMgtEx);
        throw new MobileApplicationException(errorMsg, devMgtEx);
      }

    } else if (MDMAppConstants.DEVICE.equals(applicationOperationAction.getType())) {
      DeviceIdentifier deviceIdentifier;
      for (String param : applicationOperationAction.getParams()) {
        deviceIdentifier = new DeviceIdentifier();
        if (isValidJSON(param)) {
          JSONParser parser = new JSONParser();
          try {
            JSONObject parsedObj = (JSONObject) parser.parse(param);
            deviceIdentifier.setId((String) parsedObj.get(MDMAppConstants.ID));
            deviceIdentifier.setType((String) parsedObj.get(MDMAppConstants.TYPE));
            deviceIdentifiers.add(deviceIdentifier);
          } catch (ParseException e) {
            logError("Device Identifier is not valid json object.", e);
            throw new MobileApplicationException(e);
          }
        }
      }
    } else {
      throw new IllegalStateException("invalid type is received from app store.");
    }
    App app = applicationOperationAction.getApp();
    MobileApp mobileApp = new MobileApp();
    mobileApp.setId(app.getId());
    mobileApp.setType(MobileAppTypes.valueOf(app.getType().toUpperCase()));
    mobileApp.setAppIdentifier(app.getAppIdentifier());
    mobileApp.setIconImage(app.getIconImage());
    mobileApp.setIdentifier(app.getIdentifier());
    mobileApp.setLocation(app.getLocation());
    mobileApp.setName(app.getName());
    mobileApp.setPackageName(app.getPackageName());
    mobileApp.setPlatform(app.getPlatform());
    mobileApp.setVersion(app.getVersion());
    Properties properties = new Properties();

    if (MDMAppConstants.IOS.equals(app.getPlatform())) {
      if (MDMAppConstants.ENTERPRISE.equals(app.getType())) {
        properties.put(MDMAppConstants.IOSConstants.IS_REMOVE_APP, true);
        properties.put(MDMAppConstants.IOSConstants.IS_PREVENT_BACKUP, true);
      } else if (MDMAppConstants.IOSConstants.PUBLIC.equals(app.getType())) {
        properties.put(MDMAppConstants.IOSConstants.I_TUNES_ID, app.getIdentifier());
        properties.put(MDMAppConstants.IOSConstants.IS_REMOVE_APP, true);
        properties.put(MDMAppConstants.IOSConstants.IS_PREVENT_BACKUP, true);
      } else if (MDMAppConstants.WEBAPP.equals(app.getType())) {
        properties.put(MDMAppConstants.IOSConstants.LABEL, app.getName());
        properties.put(MDMAppConstants.IOSConstants.IS_REMOVE_APP, true);
      }
    } else if (MDMAppConstants.WEBAPP.equals(app.getPlatform())) {
      properties.put(MDMAppConstants.IOSConstants.LABEL, app.getName());
      properties.put(MDMAppConstants.IOSConstants.IS_REMOVE_APP, true);
    }
    mobileApp.setProperties(properties);
    try {
      for (DeviceIdentifier deviceIdentifier : deviceIdentifiers) {
        if (deviceIdentifier.getType().equalsIgnoreCase(Platform.ANDROID.toString())) {
          if (MDMAppConstants.INSTALL.equals(applicationOperationAction.getAction())) {
            operation =
                AndroidApplicationOperationUtil.createInstallAppOperation(
                    mobileApp, applicationOperationAction.getSchedule());
          } else if (MDMAppConstants.UPDATE.equals(applicationOperationAction.getAction())) {
            operation =
                AndroidApplicationOperationUtil.createUpdateAppOperation(
                    mobileApp, applicationOperationAction.getSchedule());

          } else {
            operation =
                AndroidApplicationOperationUtil.createAppUninstallOperation(
                    mobileApp, applicationOperationAction.getSchedule());
          }
        } else if (deviceIdentifier.getType().equalsIgnoreCase(Platform.IOS.toString())) {
          if (MDMAppConstants.INSTALL.equals(applicationOperationAction.getAction())) {
            operation = IOSApplicationOperationUtil.createInstallAppOperation(mobileApp);
          } else {
            operation = IOSApplicationOperationUtil.createAppUninstallOperation(mobileApp);
          }
        }
        Activity activity =
            MDMServiceAPIUtils.getAppManagementService(applicationOperationAction.getTenantId())
                .installApplicationForDevices(operation, deviceIdentifiers);

        return activity.getActivityId();
      }
    } catch (DeviceApplicationException mdmExce) {
      logError("Error in creating operation object using app.", mdmExce);
      throw new MobileApplicationException(mdmExce.getMessage());
    } catch (ApplicationManagementException appMgtExce) {
      logError("Error in app installation.", appMgtExce);
      throw new MobileApplicationException(appMgtExce.getErrorMessage());
    }
    return null;
  }