/**
   * @param applicationOperationDevice holds the information needs to retrieve device list.
   * @return List of devices
   * @throws MobileApplicationException
   */
  public List<Device> getDevices(ApplicationOperationDevice applicationOperationDevice)
      throws MobileApplicationException {

    List<Device> devices;
    try {
      List<org.wso2.carbon.device.mgt.common.Device> deviceList =
          MDMServiceAPIUtils.getDeviceManagementService(applicationOperationDevice.getTenantId())
              .getDevicesOfUser(applicationOperationDevice.getCurrentUser().getUsername());
      devices = new ArrayList<>(deviceList.size());
      if (log.isDebugEnabled()) {
        log.debug("device list got from mdm " + deviceList.toString());
      }
      for (org.wso2.carbon.device.mgt.common.Device commonDevice : deviceList) {
        if (MDMAppConstants.ACTIVE.equals(
            commonDevice.getEnrolmentInfo().getStatus().toString().toLowerCase())) {
          Device device = new Device();
          org.wso2.carbon.appmgt.mobile.beans.DeviceIdentifier deviceIdentifier =
              new org.wso2.carbon.appmgt.mobile.beans.DeviceIdentifier();
          deviceIdentifier.setId(commonDevice.getDeviceIdentifier());
          deviceIdentifier.setType(commonDevice.getType());
          device.setDeviceIdentifier(deviceIdentifier);
          device.setName(commonDevice.getName());
          device.setModel(commonDevice.getName());
          device.setType(MDMAppConstants.MOBILE_DEVICE);
          String imgUrl;
          if (MDMAppConstants.ANDROID.equalsIgnoreCase(commonDevice.getType())) {
            imgUrl =
                String.format(
                    applicationOperationDevice.getConfigParams().get(MDMAppConstants.IMAGE_URL),
                    MDMAppConstants.NEXUS);
          } else if (MDMAppConstants.IOS.equalsIgnoreCase(commonDevice.getType())) {
            imgUrl =
                String.format(
                    applicationOperationDevice.getConfigParams().get(MDMAppConstants.IMAGE_URL),
                    MDMAppConstants.IPHONE);
          } else {
            imgUrl =
                String.format(
                    applicationOperationDevice.getConfigParams().get(MDMAppConstants.IMAGE_URL),
                    MDMAppConstants.NONE);
          }
          device.setImage(imgUrl);
          device.setPlatform(commonDevice.getType());
          devices.add(device);
        }
      }
    } catch (DeviceManagementException e) {
      logError("Error While retrieving Device List.", e);
      throw new MobileApplicationException(e.getMessage());
    }
    return devices;
  }
  /**
   * @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;
  }