/**
  * Set compliance of the feature according to the device status for the specific feature.
  *
  * @param activeFeature
  * @param deviceFeature
  * @return Returns setting up compliance feature.
  */
 public ComplianceFeature setComplianceFeatures(
     ProfileFeature activeFeature, Profile deviceFeature) {
   ComplianceFeature complianceFeature = new ComplianceFeature();
   complianceFeature.setFeature(activeFeature);
   complianceFeature.setFeatureCode(activeFeature.getFeatureCode());
   complianceFeature.setCompliance(deviceFeature.isCompliance());
   return complianceFeature;
 }
  /**
   * Generate Compliance Features.
   *
   * @param syncmlDocument syncmlDocument object parsed from the syncml engine.
   * @throws NotificationManagementException
   * @throws FeatureManagementException
   * @throws PolicyComplianceException
   */
  public void generateComplianceFeatureStatus(SyncmlDocument syncmlDocument)
      throws NotificationManagementException, FeatureManagementException, PolicyComplianceException,
          WindowsDeviceEnrolmentException, WindowsOperationException {
    List<Profile> profiles = generateDeviceOperationStatusObject(syncmlDocument);
    DeviceIdentifier deviceIdentifier =
        convertToDeviceIdentifierObject(syncmlDocument.getHeader().getSource().getLocURI());
    boolean isCompliance = false;
    if (profiles.size() != Constants.EMPTY) {
      try {
        if (WindowsAPIUtils.getPolicyManagerService()
                .getAppliedPolicyToDevice(deviceIdentifier)
                .getProfile()
                .getProfileFeaturesList()
            != null) {
          List<ProfileFeature> profileFeatures =
              WindowsAPIUtils.getPolicyManagerService()
                  .getAppliedPolicyToDevice(deviceIdentifier)
                  .getProfile()
                  .getProfileFeaturesList();
          List<ComplianceFeature> complianceFeatures = new ArrayList<>();
          for (ProfileFeature activeFeature : profileFeatures) {
            JSONObject policyContent = new JSONObject(activeFeature.getContent().toString());

            for (Profile deviceFeature : profiles) {
              if (deviceFeature.getFeatureCode().equals(activeFeature.getFeatureCode())
                  && (PluginConstants.OperationCodes.CAMERA.equals(
                      deviceFeature.getFeatureCode()))) {
                if (policyContent.getBoolean(PluginConstants.PolicyConfigProperties.POLICY_ENABLE)
                    == (deviceFeature.isEnable())) {
                  isCompliance = true;
                  deviceFeature.setCompliance(isCompliance);
                } else {
                  deviceFeature.setCompliance(isCompliance);
                }
                ComplianceFeature complianceFeature =
                    setComplianceFeatures(activeFeature, deviceFeature);
                complianceFeatures.add(complianceFeature);
              }
              if (deviceFeature.getFeatureCode().equals(activeFeature.getFeatureCode())
                  && (PluginConstants.OperationCodes.ENCRYPT_STORAGE.equals(
                      deviceFeature.getFeatureCode()))) {
                if (policyContent.getBoolean(
                        PluginConstants.PolicyConfigProperties.ENCRYPTED_ENABLE)
                    == (deviceFeature.isEnable())) {
                  isCompliance = true;
                  deviceFeature.setCompliance(isCompliance);
                } else {
                  deviceFeature.setCompliance(isCompliance);
                }
                ComplianceFeature complianceFeature =
                    setComplianceFeatures(activeFeature, deviceFeature);
                complianceFeatures.add(complianceFeature);
              }
              if (deviceFeature.getFeatureCode().equals(activeFeature.getFeatureCode())
                  && (PluginConstants.OperationCodes.PASSCODE_POLICY.equals(
                      deviceFeature.getFeatureCode()))) {
                if (policyContent.getBoolean(PluginConstants.PolicyConfigProperties.ENABLE_PASSWORD)
                    == (deviceFeature.isEnable())) {
                  isCompliance = true;
                  deviceFeature.setCompliance(isCompliance);
                } else {
                  deviceFeature.setCompliance(isCompliance);
                }
                ComplianceFeature complianceFeature =
                    setComplianceFeatures(activeFeature, deviceFeature);
                complianceFeatures.add(complianceFeature);
              }
            }
          }
          WindowsAPIUtils.getPolicyManagerService()
              .checkPolicyCompliance(deviceIdentifier, complianceFeatures);
        }
      } catch (JSONException e) {
        String msg = "Error occurred while parsing json object.";
        log.error(msg);
        throw new WindowsDeviceEnrolmentException(msg, e);
      } catch (PolicyComplianceException e) {
        String msg = "Error occurred while setting up policy compliance.";
        log.error(msg, e);
        throw new PolicyComplianceException(msg, e);
      } catch (PolicyManagementException e) {
        String msg = "Error occurred while getting effective policy.";
        log.error(msg, e);
        throw new PolicyComplianceException(msg, e);
      }
    }
  }
  /**
   * Generate status of the features that have been activated on the device.
   *
   * @param syncmlDocument syncmlDocument object pasrsed from the syncml engine.
   * @return device statuses for the activated features
   * @throws NotificationManagementException
   */
  public List<Profile> generateDeviceOperationStatusObject(SyncmlDocument syncmlDocument)
      throws NotificationManagementException, WindowsOperationException {

    DeviceIdentifier deviceIdentifier =
        convertToDeviceIdentifierObject(syncmlDocument.getHeader().getSource().getLocURI());
    String lockUri = null;
    ResultsTag result = syncmlDocument.getBody().getResults();

    List<Profile> profiles = new ArrayList<>();
    if (result != null) {
      List<ItemTag> results = result.getItem();
      for (OperationCode.Info info : OperationCode.Info.values()) {
        if (PluginConstants.OperationCodes.PIN_CODE.equals(info.name())) {
          lockUri = info.getCode();
        }
      }
      for (ItemTag item : results) {
        for (OperationCode.Info info : OperationCode.Info.values()) {
          if (item.getSource().getLocURI().equals(info.getCode())
              && PluginConstants.OperationCodes.CAMERA_STATUS.equals(info.name())) {
            Profile cameraProfile = new Profile();
            cameraProfile.setFeatureCode(PluginConstants.OperationCodes.CAMERA);
            cameraProfile.setData(item.getData());
            if ((PluginConstants.SyncML.SYNCML_DATA_ONE.equals(item.getData()))) {
              cameraProfile.setEnable(true);
            } else {
              cameraProfile.setEnable(false);
            }
            profiles.add(cameraProfile);
          }
          if (item.getSource().getLocURI().equals(info.getCode())
              && PluginConstants.OperationCodes.ENCRYPT_STORAGE_STATUS.equals(info.name())) {
            Profile encryptStorage = new Profile();
            encryptStorage.setFeatureCode(PluginConstants.OperationCodes.ENCRYPT_STORAGE);
            encryptStorage.setData(item.getData());
            if ((PluginConstants.SyncML.SYNCML_DATA_ONE.equals(item.getData()))) {
              encryptStorage.setEnable(true);
            } else {
              encryptStorage.setEnable(false);
            }
            profiles.add(encryptStorage);
          }
          if (item.getSource().getLocURI().equals(info.getCode())
              && PluginConstants.OperationCodes.DEVICE_PASSWORD_STATUS.equals(info.name())) {
            Profile encryptStorage = new Profile();
            encryptStorage.setFeatureCode(PluginConstants.OperationCodes.PASSCODE_POLICY);
            encryptStorage.setData(item.getData());
            if ((PluginConstants.SyncML.SYNCML_DATA_ZERO.equals(item.getData()))) {
              encryptStorage.setEnable(true);
            } else {
              encryptStorage.setEnable(false);
            }
            profiles.add(encryptStorage);
          }
          if (!item.getData().isEmpty() && item.getSource().getLocURI().equals(lockUri)) {
            String pinValue = item.getData();
            NotificationManagementService nmService =
                WindowsAPIUtils.getNotificationManagementService();
            Notification notification = new Notification();
            notification.setDescription("Auto generated DevicePin : " + pinValue);
            notification.setOperationId(result.getCommandReference());
            notification.setDeviceIdentifier(deviceIdentifier);
            notification.setStatus(String.valueOf(Notification.Status.NEW));
            try {
              nmService.addNotification(notification);
            } catch (NotificationManagementException e) {
              String msg = "Failure Occurred in getting notification service.";
              log.error(msg, e);
              throw new WindowsOperationException(msg, e);
            }
            break;
          }
        }
      }
    }
    return profiles;
  }