regulators: Create System class

Create a C++ class that represents the entire computer system being
controlled and monitored by the BMC.

The system contains one or more chassis.  Chassis are large enclosures
that can be independently powered off and on by the BMC.

Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: Iba40637a229c1787b017e7f19b011192621a5d23
diff --git a/phosphor-regulators/src/system.hpp b/phosphor-regulators/src/system.hpp
new file mode 100644
index 0000000..3256c8d
--- /dev/null
+++ b/phosphor-regulators/src/system.hpp
@@ -0,0 +1,111 @@
+/**
+ * Copyright © 2020 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "chassis.hpp"
+#include "id_map.hpp"
+#include "rule.hpp"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+namespace phosphor::power::regulators
+{
+
+/**
+ * @class System
+ *
+ * The computer system being controlled and monitored by the BMC.
+ *
+ * The system contains one or more chassis.  Chassis are large enclosures that
+ * can be independently powered off and on by the BMC.
+ */
+class System
+{
+  public:
+    // Specify which compiler-generated methods we want
+    System() = delete;
+    System(const System&) = delete;
+    System(System&&) = delete;
+    System& operator=(const System&) = delete;
+    System& operator=(System&&) = delete;
+    ~System() = default;
+
+    /**
+     * Constructor.
+     *
+     * @param rules rules used to monitor and control regulators in the system
+     * @param chassis chassis in the system
+     */
+    explicit System(std::vector<std::unique_ptr<Rule>> rules,
+                    std::vector<std::unique_ptr<Chassis>> chassis) :
+        rules{std::move(rules)},
+        chassis{std::move(chassis)}
+    {
+    }
+
+    /**
+     * Returns the chassis in the system.
+     *
+     * @return chassis
+     */
+    const std::vector<std::unique_ptr<Chassis>>& getChassis() const
+    {
+        return chassis;
+    }
+
+    /**
+     * Returns the IDMap for the system.
+     *
+     * The IDMap provides a mapping from string IDs to the associated Device,
+     * Rail, and Rule objects.
+     *
+     * @return IDMap
+     */
+    const IDMap& getIDMap() const
+    {
+        return idMap;
+    }
+
+    /**
+     * Returns the rules used to monitor and control regulators in the system.
+     *
+     * @return rules
+     */
+    const std::vector<std::unique_ptr<Rule>>& getRules() const
+    {
+        return rules;
+    }
+
+  private:
+    /**
+     * Rules used to monitor and control regulators in the system.
+     */
+    std::vector<std::unique_ptr<Rule>> rules{};
+
+    /**
+     * Chassis in the system.
+     */
+    std::vector<std::unique_ptr<Chassis>> chassis{};
+
+    /**
+     * Mapping from string IDs to the associated Device, Rail, and Rule objects.
+     */
+    IDMap idMap{};
+};
+
+} // namespace phosphor::power::regulators
diff --git a/phosphor-regulators/test/meson.build b/phosphor-regulators/test/meson.build
index 10dace9..5f68fba 100644
--- a/phosphor-regulators/test/meson.build
+++ b/phosphor-regulators/test/meson.build
@@ -17,6 +17,7 @@
     'rail_tests.cpp',
     'rule_tests.cpp',
     'sensor_monitoring_tests.cpp',
+    'system_tests.cpp',
     'write_verification_error_tests.cpp',
 
     'actions/action_environment_tests.cpp',
diff --git a/phosphor-regulators/test/system_tests.cpp b/phosphor-regulators/test/system_tests.cpp
new file mode 100644
index 0000000..b5f33f1
--- /dev/null
+++ b/phosphor-regulators/test/system_tests.cpp
@@ -0,0 +1,95 @@
+/**
+ * Copyright © 2020 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "action.hpp"
+#include "chassis.hpp"
+#include "mock_action.hpp"
+#include "rule.hpp"
+#include "system.hpp"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+using namespace phosphor::power::regulators;
+
+TEST(SystemTests, Constructor)
+{
+    // Create Rules
+    std::vector<std::unique_ptr<Rule>> rules{};
+    std::vector<std::unique_ptr<Action>> actions{};
+    actions.emplace_back(std::make_unique<MockAction>());
+    rules.emplace_back(
+        std::make_unique<Rule>("set_voltage_rule", std::move(actions)));
+
+    // Create Chassis
+    std::vector<std::unique_ptr<Chassis>> chassis{};
+    chassis.emplace_back(std::make_unique<Chassis>(1));
+
+    // Create System
+    System system{std::move(rules), std::move(chassis)};
+    EXPECT_EQ(system.getChassis().size(), 1);
+    EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
+    // TODO: Add tests for IDMap once code to populate it is implemented
+    EXPECT_EQ(system.getRules().size(), 1);
+    EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
+}
+
+TEST(SystemTests, GetChassis)
+{
+    // Specify an empty rules vector
+    std::vector<std::unique_ptr<Rule>> rules{};
+
+    // Create Chassis
+    std::vector<std::unique_ptr<Chassis>> chassis{};
+    chassis.emplace_back(std::make_unique<Chassis>(1));
+    chassis.emplace_back(std::make_unique<Chassis>(3));
+
+    // Create System
+    System system{std::move(rules), std::move(chassis)};
+    EXPECT_EQ(system.getChassis().size(), 2);
+    EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
+    EXPECT_EQ(system.getChassis()[1]->getNumber(), 3);
+}
+
+TEST(SystemTests, GetIDMap)
+{
+    // TODO: Code to build IDMap is not implemented yet
+}
+
+TEST(SystemTests, GetRules)
+{
+    // Create Rules
+    std::vector<std::unique_ptr<Rule>> rules{};
+    std::vector<std::unique_ptr<Action>> actions{};
+    actions.emplace_back(std::make_unique<MockAction>());
+    rules.emplace_back(
+        std::make_unique<Rule>("set_voltage_rule", std::move(actions)));
+    actions.emplace_back(std::make_unique<MockAction>());
+    rules.emplace_back(
+        std::make_unique<Rule>("read_sensors_rule", std::move(actions)));
+
+    // Create Chassis
+    std::vector<std::unique_ptr<Chassis>> chassis{};
+    chassis.emplace_back(std::make_unique<Chassis>(1));
+
+    // Create System
+    System system{std::move(rules), std::move(chassis)};
+    EXPECT_EQ(system.getRules().size(), 2);
+    EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
+    EXPECT_EQ(system.getRules()[1]->getID(), "read_sensors_rule");
+}