1 /**
2  * Copyright © 2019 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "action.hpp"
19 #include "action_environment.hpp"
20 
21 #include <memory>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 namespace phosphor::power::regulators
27 {
28 
29 /**
30  * @class IfAction
31  *
32  * Performs actions based on whether a condition is true.
33  *
34  * Implements the "if" action in the JSON config file.  The "if" action provides
35  * a standard if/then/else structure within the JSON config file.
36  *
37  * The "if" action contains three parts:
38  *   - condition
39  *   - then clause
40  *   - else clause (optional)
41  *
42  * The condition is a single action.  The action is executed to determine if the
43  * condition is true.
44  *
45  * If the condition is true, the actions in the "then" clause are executed.
46  *
47  * If the condition is false, the actions in the "else" clause are executed (if
48  * specified).
49  */
50 class IfAction : public Action
51 {
52   public:
53     // Specify which compiler-generated methods we want
54     IfAction() = delete;
55     IfAction(const IfAction&) = delete;
56     IfAction(IfAction&&) = delete;
57     IfAction& operator=(const IfAction&) = delete;
58     IfAction& operator=(IfAction&&) = delete;
59     virtual ~IfAction() = default;
60 
61     /**
62      * Constructor.
63      *
64      * @param conditionAction action that tests whether condition is true
65      * @param thenActions actions to perform if condition is true
66      * @param elseActions actions to perform if condition is false (optional)
67      */
68     explicit IfAction(std::unique_ptr<Action> conditionAction,
69                       std::vector<std::unique_ptr<Action>> thenActions,
70                       std::vector<std::unique_ptr<Action>> elseActions =
71                           std::vector<std::unique_ptr<Action>>{}) :
72         conditionAction{std::move(conditionAction)},
73         thenActions{std::move(thenActions)}, elseActions{std::move(elseActions)}
74     {
75     }
76 
77     /**
78      * Executes the condition action specified in the constructor.
79      *
80      * If the condition action returns true, the actions in the "then" clause
81      * will be executed.  Returns the return value of the last action in the
82      * "then" clause.
83      *
84      * If the condition action returns false, the actions in the "else" clause
85      * will be executed.  Returns the return value of the last action in the
86      * "else" clause.  If no "else" clause was specified, returns false.
87      *
88      * Throws an exception if an error occurs and an action cannot be
89      * successfully executed.
90      *
91      * @param environment action execution environment
92      * @return return value from last action in "then" or "else" clause
93      */
94     virtual bool execute(ActionEnvironment& environment) override;
95 
96     /**
97      * Returns the action that tests whether the condition is true.
98      *
99      * @return condition action
100      */
101     const std::unique_ptr<Action>& getConditionAction() const
102     {
103         return conditionAction;
104     }
105 
106     /**
107      * Returns the actions in the "then" clause.
108      *
109      * These actions are executed if the condition is true.
110      *
111      * @return then clause actions
112      */
113     const std::vector<std::unique_ptr<Action>>& getThenActions() const
114     {
115         return thenActions;
116     }
117 
118     /**
119      * Returns the actions in the "else" clause.
120      *
121      * These actions are executed if the condition is false.
122      *
123      * @return else clause actions
124      */
125     const std::vector<std::unique_ptr<Action>>& getElseActions() const
126     {
127         return elseActions;
128     }
129 
130     /**
131      * Returns a string description of this action.
132      *
133      * @return description of action
134      */
135     virtual std::string toString() const override
136     {
137         std::string description{"if: { condition: { ... }, then: [ ... ]"};
138         if (elseActions.size() > 0)
139         {
140             description += ", else: [ ... ]";
141         }
142         description += " }";
143         return description;
144     }
145 
146   private:
147     /**
148      * Action that tests whether the condition is true.
149      */
150     std::unique_ptr<Action> conditionAction{};
151 
152     /**
153      * Actions in the "then" clause.  Executed if condition is true.
154      */
155     std::vector<std::unique_ptr<Action>> thenActions{};
156 
157     /**
158      * Actions in the "else" clause.  Executed if condition is false.  Optional.
159      */
160     std::vector<std::unique_ptr<Action>> elseActions{};
161 };
162 
163 } // namespace phosphor::power::regulators
164