/**
   * Update the common fields in the UnManagedVolume to reflect RP characteristics Is this volume
   * SOURCE, TARGET, or JOURNAL? What's the RP Copy Name of this volume? (what copy does it belong
   * to?)
   *
   * @param unManagedProtectionSet
   * @param unManagedVolume
   * @param personalityType
   * @param volume
   * @param dbClient
   */
  private void updateCommonRPProperties(
      UnManagedProtectionSet unManagedProtectionSet,
      UnManagedVolume unManagedVolume,
      String personalityType,
      GetVolumeResponse volume,
      DbClient dbClient) {
    StringSet rpCopyName = new StringSet();
    rpCopyName.add(volume.getRpCopyName());

    StringSet rpInternalSiteName = new StringSet();
    rpInternalSiteName.add(volume.getInternalSiteName());

    if (volume.isProductionStandby()) {
      unManagedVolume.putVolumeInfo(
          SupportedVolumeInformation.RP_STANDBY_COPY_NAME.toString(), rpCopyName);

      unManagedVolume.putVolumeInfo(
          SupportedVolumeInformation.RP_STANDBY_INTERNAL_SITENAME.toString(), rpInternalSiteName);

      // If this volume is flagged as production standby it indicates that this RP CG is
      // MetroPoint. Set the IS_MP flag on UnManagedProtectionSet to TRUE. This only needs
      // to be done once.
      String metroPoint =
          unManagedProtectionSet
              .getCGCharacteristics()
              .get(UnManagedProtectionSet.SupportedCGCharacteristics.IS_MP.name());
      if (metroPoint == null || metroPoint.isEmpty() || !Boolean.parseBoolean(metroPoint)) {
        // Set the flag to true if it hasn't already been set
        unManagedProtectionSet
            .getCGCharacteristics()
            .put(
                UnManagedProtectionSet.SupportedCGCharacteristics.IS_MP.name(),
                Boolean.TRUE.toString());
      }
    } else {
      unManagedVolume.putVolumeInfo(SupportedVolumeInformation.RP_COPY_NAME.toString(), rpCopyName);

      unManagedVolume.putVolumeInfo(
          SupportedVolumeInformation.RP_INTERNAL_SITENAME.toString(), rpInternalSiteName);
    }

    StringSet personality = new StringSet();
    personality.add(personalityType);
    unManagedVolume.putVolumeInfo(
        SupportedVolumeInformation.RP_PERSONALITY.toString(), personality);

    StringSet rpProtectionSystemId = new StringSet();
    rpProtectionSystemId.add(unManagedProtectionSet.getProtectionSystemUri().toString());
    unManagedVolume.putVolumeInfo(
        SupportedVolumeInformation.RP_PROTECTIONSYSTEM.toString(), rpProtectionSystemId);

    // Filter in RP source vpools, filter out everything else (if source)
    // Filter out certain vpools if target/journal

    filterProtectedVpools(dbClient, unManagedVolume, personality.iterator().next());
  }
  /**
   * Filter vpools from the qualified list. rpSource true: Filter out anything other than RP source
   * vpools rpSource false: Filter out RP and SRDF source vpools
   *
   * @param dbClient dbclient
   * @param unManagedVolume unmanaged volume
   * @param personality SOURCE, TARGET, or METADATA
   */
  private void filterProtectedVpools(
      DbClient dbClient, UnManagedVolume unManagedVolume, String personality) {

    if (unManagedVolume.getSupportedVpoolUris() != null
        && !unManagedVolume.getSupportedVpoolUris().isEmpty()) {
      Iterator<VirtualPool> vpoolItr =
          dbClient.queryIterativeObjects(
              VirtualPool.class, URIUtil.toURIList(unManagedVolume.getSupportedVpoolUris()));
      while (vpoolItr.hasNext()) {
        boolean remove = false;
        VirtualPool vpool = vpoolItr.next();

        // If this is an SRDF source vpool, we can filter out since we're dealing with an RP volume
        if (vpool.getProtectionRemoteCopySettings() != null) {
          remove = true;
        }

        // If this is not an RP source, the vpool should be filtered out if:
        // The vpool is an RP vpool (has settings) and target vpools are non-null
        if (vpool.getProtectionVarraySettings() != null
            && ((Volume.PersonalityTypes.TARGET.name().equalsIgnoreCase(personality))
                || Volume.PersonalityTypes.METADATA.name().equalsIgnoreCase(personality))) {
          boolean foundEmptyTargetVpool = false;
          Map<URI, VpoolProtectionVarraySettings> settings =
              VirtualPool.getProtectionSettings(vpool, dbClient);
          for (Map.Entry<URI, VpoolProtectionVarraySettings> setting : settings.entrySet()) {
            if (NullColumnValueGetter.isNullURI(setting.getValue().getVirtualPool())) {
              foundEmptyTargetVpool = true;
              break;
            }
          }

          // If this is a journal volume, also check the journal vpools. If they're not set, we
          // cannot filter out this vpool.
          if (Volume.PersonalityTypes.METADATA.name().equalsIgnoreCase(personality)
              && (NullColumnValueGetter.isNullValue(vpool.getJournalVpool())
                  || NullColumnValueGetter.isNullValue(vpool.getStandbyJournalVpool()))) {
            foundEmptyTargetVpool = true;
          }

          // If every relevant target (and journal for journal volumes) vpool is filled-in, then
          // you would never assign your target volume to this source vpool, so filter it out.
          if (!foundEmptyTargetVpool) {
            remove = true;
          }
        }

        if (Volume.PersonalityTypes.SOURCE.name().equalsIgnoreCase(personality)) {
          if (!VirtualPool.vPoolSpecifiesProtection(vpool)) {
            // If this an RP source, the vpool must be an RP vpool
            remove = true;
          } else if (unManagedVolume
                  .getVolumeInformation()
                  .containsKey(SupportedVolumeInformation.RP_STANDBY_INTERNAL_SITENAME.toString())
              && !VirtualPool.vPoolSpecifiesMetroPoint(vpool)) {
            // Since this is a Source volume with the presence of RP_STANDBY_INTERNAL_SITENAME
            // it indicates that this volume is MetroPoint, if we get here, this is vpool
            // must be filtered out since it's not MP.
            remove = true;
          }
        }

        if (remove) {
          log.info(
              "Removing virtual pool "
                  + vpool.getLabel()
                  + " from supported vpools for unmanaged volume: "
                  + unManagedVolume.getLabel());
          unManagedVolume.getSupportedVpoolUris().remove(vpool.getId().toString());
        }
      }
    }
  }