#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>
#include <memory>
#define REGISTER_SUCCESS "REGISTER_SUCCESS"
using namespace std;
class AlarmCheck {
public:
virtual void addAlarmsExpect(const std::vector<std::string> &alarms_expect_vector) {
alarms_map_.insert(alarms_expect_vector.begin(), alarms_expect_vector.end());
}
virtual void addAlarmsExpect(const std::string &alarms_expect) {
alarms_map_.insert(alarms_expect);
}
virtual bool addAlarmActualAndCheck(const std::string &alarm) = 0;
virtual bool isPassed() {
return passed_;
}
protected:
bool has_failed_ = false;
bool passed_ = false;
std::unordered_set<std::string> alarms_map_;
std::vector<std::string> alarms_vector_;
};
class AlarmCheckAny : public AlarmCheck {
public:
virtual bool addAlarmActualAndCheck(const std::string &alarm) override;
};
bool AlarmCheckAny::addAlarmActualAndCheck(const std::string &alarm) {
if (passed_) return true;
if (alarms_map_.find(alarm) == alarms_map_.end()) return false;
passed_ = true;
return true;
}
class AlarmCheckAll : public AlarmCheck {
public:
virtual bool addAlarmActualAndCheck(const std::string &alarm) override;
virtual bool isPassed() override;
};
bool AlarmCheckAll::isPassed() {
return alarms_map_.empty();
}
bool AlarmCheckAll::addAlarmActualAndCheck(const std::string &alarm) {
if (alarms_map_.empty()) return true;
if (alarms_map_.find(alarm) == alarms_map_.end()) return false;
alarms_map_.erase(alarm);
return alarms_map_.empty();
}
class AlarmCheckSort : public AlarmCheck {
public:
virtual bool addAlarmActualAndCheck(const std::string &alarm) override;
virtual bool isPassed() override;
virtual void addAlarmsExpect(const std::vector<std::string> &alarms_expect_vector) override;
virtual void addAlarmsExpect(const std::string &alarms_expect) override;
private:
int index_ = 0;
};
void AlarmCheckSort::addAlarmsExpect(const std::vector<std::string> &alarms_expect_vector) {
for(auto &alarms_expect : alarms_expect_vector) {
addAlarmsExpect(alarms_expect);
}
}
void AlarmCheckSort::addAlarmsExpect(const std::string &alarms_expect) {
auto result = alarms_map_.insert(alarms_expect);
if(result.second) {
alarms_vector_.push_back(alarms_expect);
}
}
bool AlarmCheckSort::addAlarmActualAndCheck(const std::string &alarm) {
if(has_failed_) return false;
if(alarms_map_.find(alarm) == alarms_map_.end()) return false;
if(alarm == alarms_vector_.at(index_)) {
return true;
}
int next_index = index_ + 1;
if (next_index >= alarms_vector_.size()) {
has_failed_ = true;
return false;
}
if (alarms_vector_.at(next_index) == alarm) {
index_ = next_index;
return true;
}
has_failed_ = true;
return false;
}
bool AlarmCheckSort::isPassed() {
if(has_failed_) return false;
return index_ == alarms_vector_.size() - 1;
}
class AlarmCheckRegisterMax : public AlarmCheck {
public:
virtual bool addAlarmActualAndCheck(const std::string &alarm) override;
void setMax (int max) {
max_value_ = max;
}
private:
int max_value_ = 0;
int count_ = 0;
};
bool AlarmCheckRegisterMax::addAlarmActualAndCheck(const std::string &alarm) {
if (has_failed_) return false;
if (alarm == REGISTER_SUCCESS) {
count_++;
if(count_ > max_value_) has_failed_ = true;
passed_ = false;
return false;
}
if (alarm == "-50141") {
if(count_ == max_value_) {
passed_ = true;
return true;
}
has_failed_ = true;
return false;
}
return false;
}
class AlarmFactory {
public:
static std::unique_ptr<AlarmCheck> createObj(const std::string& checkMode) {
if (checkMode == "any") {
return std::make_unique<AlarmCheckAny>();
} else if (checkMode == "all") {
return std::make_unique<AlarmCheckAll>();
} else if (checkMode == "sort") {
return std::make_unique<AlarmCheckSort>();
} else if (checkMode == "register_max") {
return std::make_unique<AlarmCheckRegisterMax>();
} {
throw std::invalid_argument("Unknown check mode: " + checkMode);
}
}
};
int main() {
bool res;
cout << "test AlarmCheckAll" << endl;
auto alarmCheck2 = AlarmFactory::createObj("all");
alarmCheck2->addAlarmsExpect(std::vector<std::string>{"-50121", "drowsy", "-50103"});
res = alarmCheck2->addAlarmActualAndCheck("0");
cout << res << endl;
res = alarmCheck2->addAlarmActualAndCheck("-50121");
cout << res << endl;
res = alarmCheck2->addAlarmActualAndCheck("drowsy");
cout << res << endl;
res = alarmCheck2->addAlarmActualAndCheck("-50103");
cout << res << endl;
res = alarmCheck2->addAlarmActualAndCheck("-50113");
cout << res << endl;
cout << "test AlarmCheckRegisterMax" << endl;
AlarmCheckRegisterMax alarmCheck3{};
alarmCheck3.setMax(10);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
res = alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
cout << res << endl;
res = alarmCheck3.addAlarmActualAndCheck("-50141");
cout << res << endl;
res = alarmCheck3.addAlarmActualAndCheck(REGISTER_SUCCESS);
cout << res << endl;
res = alarmCheck3.addAlarmActualAndCheck("-50141");
cout << res << endl;
cout << "test AlarmCheckSort" << endl;
AlarmCheckSort alarmCheck4{};
alarmCheck4.addAlarmsExpect(std::vector<std::string>{"smoke", "smoke end"});
res = alarmCheck4.addAlarmActualAndCheck("smoke");
cout << res << endl;
res = alarmCheck4.addAlarmActualAndCheck("smoke");
cout << res << endl;
cout << "ispassed:" << alarmCheck4.isPassed() << endl;
res = alarmCheck4.addAlarmActualAndCheck("smoke end");
cout << res << endl;
cout << "ispassed:" << alarmCheck4.isPassed() << endl;
res = alarmCheck4.addAlarmActualAndCheck("smoke end");
cout << res << endl;
cout << "ispassed:" << alarmCheck4.isPassed() << endl;
res = alarmCheck4.addAlarmActualAndCheck("smoke");
cout << res << endl;
cout << "ispassed:" << alarmCheck4.isPassed() << endl;
res = alarmCheck4.addAlarmActualAndCheck("smoke end");
cout << res << endl;
cout << "ispassed:" << alarmCheck4.isPassed() << endl;
return 0;
}