PNOR: Switch Software Version based on priority.

If the user specifically sets the priority of a version
to the lowest value, then we need to update the symlinks
and change PNOR current version.

Change-Id: I8bb46800e30ec0afd7726cceb8566915a48b5e88
Signed-off-by: Saqib Khan <khansa@us.ibm.com>
diff --git a/activation.cpp b/activation.cpp
index fd238d0..3d70811 100755
--- a/activation.cpp
+++ b/activation.cpp
@@ -27,6 +27,37 @@
     return;
 }
 
+void Activation::createSymlinks()
+{
+    if (!fs::is_directory(PNOR_ACTIVE_PATH))
+    {
+        fs::create_directories(PNOR_ACTIVE_PATH);
+    }
+
+    // If the RW or RO active links exist, remove them and create new
+    // ones pointing to the active version.
+    if (fs::is_symlink(PNOR_RO_ACTIVE_PATH))
+    {
+        fs::remove(PNOR_RO_ACTIVE_PATH);
+    }
+    fs::create_directory_symlink(PNOR_RO_PREFIX + versionId,
+            PNOR_RO_ACTIVE_PATH);
+    if (fs::is_symlink(PNOR_RW_ACTIVE_PATH))
+    {
+        fs::remove(PNOR_RW_ACTIVE_PATH);
+    }
+    fs::create_directory_symlink(PNOR_RW_PREFIX + versionId,
+            PNOR_RW_ACTIVE_PATH);
+
+    // There is only one preserved directory as it is not tied to a
+    // version, so just create the link if it doesn't exist already
+    if (!fs::is_symlink(PNOR_PRSV_ACTIVE_PATH))
+    {
+        fs::create_directory_symlink(PNOR_PRSV,
+                PNOR_PRSV_ACTIVE_PATH);
+    }
+}
+
 auto Activation::activation(Activations value) ->
         Activations
 {
@@ -104,34 +135,7 @@
                 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
             {
                 activationProgress->progress(90);
-
-                if (!fs::is_directory(PNOR_ACTIVE_PATH))
-                {
-                    fs::create_directories(PNOR_ACTIVE_PATH);
-                }
-
-                // If the RW or RO active links exist, remove them and create new
-                // ones pointing to the active version.
-                if (fs::is_symlink(PNOR_RO_ACTIVE_PATH))
-                {
-                    fs::remove(PNOR_RO_ACTIVE_PATH);
-                }
-                fs::create_directory_symlink(PNOR_RO_PREFIX + versionId,
-                        PNOR_RO_ACTIVE_PATH);
-                if (fs::is_symlink(PNOR_RW_ACTIVE_PATH))
-                {
-                    fs::remove(PNOR_RW_ACTIVE_PATH);
-                }
-                fs::create_directory_symlink(PNOR_RW_PREFIX + versionId,
-                        PNOR_RW_ACTIVE_PATH);
-
-                // There is only one preserved directory as it is not tied to a
-                // version, so just create the link if it doesn't exist already.
-                if (!fs::is_symlink(PNOR_PRSV_ACTIVE_PATH))
-                {
-                    fs::create_directory_symlink(PNOR_PRSV,
-                            PNOR_PRSV_ACTIVE_PATH);
-                }
+                createSymlinks();
 
                 // Set Redundancy Priority before setting to Active
                 if (!redundancyPriority)
@@ -207,6 +211,14 @@
 uint8_t RedundancyPriority::priority(uint8_t value)
 {
     parent.parent.freePriority(value);
+
+    if(parent.parent.isLowestPriority(value))
+    {
+        // Need to update the symlinks to point to Software Version
+        // with lowest priority.
+        parent.createSymlinks();
+    }
+
     return softwareServer::RedundancyPriority::priority(value);
 }
 
diff --git a/activation.hpp b/activation.hpp
index 458034c..bc99fbe 100755
--- a/activation.hpp
+++ b/activation.hpp
@@ -226,6 +226,9 @@
         RequestedActivations requestedActivation(RequestedActivations value)
                 override;
 
+        /** @brief Create symlinks for the current Software Version */
+        void createSymlinks();
+
         /** @brief Check if systemd state change is relevant to this object
          *
          * Instance specific interface to handle the detected systemd state
diff --git a/item_updater.cpp b/item_updater.cpp
index 7a56775..7466d12 100755
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -227,6 +227,21 @@
     }
 }
 
+bool ItemUpdater::isLowestPriority(uint8_t value)
+{
+    for (const auto& intf : activations)
+    {
+        if(intf.second->redundancyPriority)
+        {
+            if (intf.second->redundancyPriority.get()->priority() < value)
+            {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
 } // namespace updater
 } // namespace software
 } // namespace openpower
diff --git a/item_updater.hpp b/item_updater.hpp
index 2a71905..213b456 100755
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -51,6 +51,15 @@
          */
         void freePriority(uint8_t value);
 
+        /** @brief Determine is the given priority is the lowest
+         *
+         *  @param[in] value - The priority that needs to be checked.
+         *
+         *  @return boolean corresponding to whether the given
+         *           priority is lowest.
+         */
+        bool isLowestPriority(uint8_t value);
+
         /**
          * @brief Create and populate the active PNOR Version.
          */