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      * Executes the condition action specified in the constructor.
78      *
79      * If the condition action returns true, the actions in the "then" clause
80      * will be executed.  Returns the return value of the last action in the
81      * "then" clause.
82      *
83      * If the condition action returns false, the actions in the "else" clause
84      * will be executed.  Returns the return value of the last action in the
85      * "else" clause.  If no "else" clause was specified, returns false.
86      *
87      * Throws an exception if an error occurs and an action cannot be
88      * successfully executed.
89      *
90      * @param environment action execution environment
91      * @return return value from last action in "then" or "else" clause
92      */
93     virtual bool execute(ActionEnvironment& environment) override;
94 
95     /**
96      * Returns the action that tests whether the condition is true.
97      *
98      * @return condition action
99      */
100     const std::unique_ptr<Action>& getConditionAction() const
101     {
102         return conditionAction;
103     }
104 
105     /**
106      * Returns the actions in the "then" clause.
107      *
108      * These actions are executed if the condition is true.
109      *
110      * @return then clause actions
111      */
112     const std::vector<std::unique_ptr<Action>>& getThenActions() const
113     {
114         return thenActions;
115     }
116 
117     /**
118      * Returns the actions in the "else" clause.
119      *
120      * These actions are executed if the condition is false.
121      *
122      * @return else clause actions
123      */
124     const std::vector<std::unique_ptr<Action>>& getElseActions() const
125     {
126         return elseActions;
127     }
128 
129     /**
130      * Returns a string description of this action.
131      *
132      * @return description of action
133      */
134     virtual std::string toString() const override
135     {
136         std::string description{"if: { condition: { ... }, then: [ ... ]"};
137         if (elseActions.size() > 0)
138         {
139             description += ", else: [ ... ]";
140         }
141         description += " }";
142         return description;
143     }
144 
145   private:
146     /**
147      * Action that tests whether the condition is true.
148      */
149     std::unique_ptr<Action> conditionAction{};
150 
151     /**
152      * Actions in the "then" clause.  Executed if condition is true.
153      */
154     std::vector<std::unique_ptr<Action>> thenActions{};
155 
156     /**
157      * Actions in the "else" clause.  Executed if condition is false.  Optional.
158      */
159     std::vector<std::unique_ptr<Action>> elseActions{};
160 };
161 
162 } // namespace phosphor::power::regulators
163