-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlogread.cpp
More file actions
154 lines (135 loc) · 5.33 KB
/
logread.cpp
File metadata and controls
154 lines (135 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "log_utils.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <sstream>
using std::cout; using std::endl; using std::string; using std::vector; using std::cerr;
using std::ifstream; using std::map; using std::set; using std::getline; using std::istringstream;
using std::stoi; using std::invalid_argument; using std::out_of_range;
int main(int argc, char* argv[]) {
string token, logFile, queryType, personType, personName;
vector<string> persons;
bool multiplePersons = false;
// Parse command-line arguments
for (int i = 1; i < argc; i++) {
string arg = argv[i];
if (arg == "-K") token = argv[++i];
else if (arg == "-S") queryType = "State";
else if (arg == "-R") queryType = "RoomList";
//else if (arg == "-T") queryType = "TotalTime"; //not implemented
//else if (arg == "-I") { queryType = "SharedRooms"; multiplePersons = true; } //not implemented
else if (arg == "-E") { personType = "Employee"; persons.push_back(argv[++i]); }
else if (arg == "-G") { personType = "Guest"; persons.push_back(argv[++i]); }
else logFile = argv[i];
}
// Check if only one query type is specified
if (queryType.empty() || logFile.empty() || token.empty()) {
cerr << "invalid" << endl;
return 255;
}
auto envVars = loadEnv(".env");
string encryptionKey = envVars["ENCRYPTION_KEY"];
string secret = envVars["SECRET"];
// Load and encrypt the stored token for verification
string storedEncryptedToken = encryptData(secret, encryptionKey);
// Verify provided token
if (!verifyToken(token, storedEncryptedToken, encryptionKey)) {
cerr << "integrity violation" << endl;
return 255;
}
// Open the log file for reading
ifstream log(logFile);
if (!log.is_open()) {
cerr << "integrity violation" << endl;
return 255;
}
// Variables to store gallery state
set<string> employeesInGallery, guestsInGallery;
map<int, set<string>> roomOccupancy;
map<string, vector<int>> personRoomHistory;
string EncryptedLogEntry;
while (getline(log, EncryptedLogEntry)) {
string logEntry = decryptData(EncryptedLogEntry, encryptionKey);
// Parse the log entry to determine event type and update the state
istringstream entryStream(logEntry);
string timestamp, type, name, action, roomStr;
int roomID = -1;
// Parse log entry assuming format: timestamp, type, name, action[, Room:roomID]
getline(entryStream, timestamp, ',');
getline(entryStream, type, ',');
getline(entryStream, name, ',');
getline(entryStream, action, ',');
// Check if a room is specified in the format "Room:roomID"
if (getline(entryStream, roomStr)) {
size_t pos = roomStr.find("Room:");
if (pos != string::npos) {
try {
roomID = stoi(roomStr.substr(pos + 5)); // Parse room number after "Room:"
}
catch (const invalid_argument& e) {
cerr << "Invalid log entry" << endl;
continue;
}
catch (const out_of_range& e) {
cerr << "Invalid log entry" << endl;
continue;
}
}
}
// Process entry based on action and type
if (action == "Arrival") {
if (roomID == -1) {
// Arrival to gallery
if (type == "Employee") employeesInGallery.insert(name);
else if (type == "Guest") guestsInGallery.insert(name);
}
else {
// Arrival to room
roomOccupancy[roomID].insert(name);
personRoomHistory[name].push_back(roomID);
}
}
else if (action == "Leave") {
if (roomID == -1) {
// Leave the gallery
if (type == "Employee") employeesInGallery.erase(name);
else if (type == "Guest") guestsInGallery.erase(name);
}
else {
// Leave a specific room
roomOccupancy[roomID].erase(name);
}
}
}
log.close();
// Process the query type
if (queryType == "State") {
// Output current state of employees and guests in gallery
for (const auto& emp : employeesInGallery) cout << emp << ",";
cout << "\n";
for (const auto& guest : guestsInGallery) cout << guest << ",";
// Room-by-room listing
for (const auto& room : roomOccupancy) {
int roomID = room.first;
const set<string>& occupants = room.second;
cout << "\n" << roomID << ": ";
for (const auto& person : occupants) cout << person << ",";
}
cout << endl;
}
else if (queryType == "RoomList") {
if (persons.size() != 1) { cerr << "invalid" << endl; return 255; }
// List rooms entered by the specified person in chronological order
auto& roomHistory = personRoomHistory[persons[0]];
for (size_t i = 0; i < roomHistory.size(); ++i) {
if (i > 0) cout << ",";
cout << roomHistory[i];
}
cout << endl;
}
return 0;
}