//
// SCUT13J.cpp
// playground
//
// Created by Adam Chang on 2015/05/17.
// Copyright (c) 2015年 Adam Chang. All rights reserved.
//
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <set>
#include <stack>
#include <cmath>
#include <map>
using namespace std;
struct msgType{
int type;//1 for say;2 for friendship
string arg1;
string arg2;
string timeStamp;
msgType(string _timeStamp,int _type,string _arg1,string _arg2){
type = _type;
timeStamp = _timeStamp;
arg1 = _arg1;//hadle / usr1
arg2 = _arg2;//message body/usr2
}
};
struct userType{
string handle;
bool isLogin;
set<string> friendList;
stack<int> msgstk;
userType(string _handle){
handle = _handle;
isLogin = false;
friendList.clear();
while(!msgstk.empty()){
msgstk.pop();
}
}
userType(){
handle.clear();
isLogin = false;
friendList.clear();
while(!msgstk.empty()){
msgstk.pop();
}
}
};
void profile(string &handle);
map<string, userType> userbase;
vector<msgType> msgbase;
int caseCnt = 0;
bool isSystemOnline = false;
void poweron(string &timeStamp){
if(isSystemOnline){
return;
}else{
isSystemOnline = true;
userbase.clear();
msgbase.clear();
cout << "Case " << ++caseCnt << ':' << endl;
cout << timeStamp << " New System Started." << endl;
}
}
void poweroff(string &timeStamp){
if (!isSystemOnline) {
return;
}else{
isSystemOnline = false;
cout << timeStamp << " System Shutdown." << endl;
}
}
void useradd(string &timeStamp,string &_handle){
if (!isSystemOnline) {
return;
}
if (userbase.count(_handle)) {
return;
}else{
userbase[_handle] = userType(_handle);
cout << timeStamp << ' ' << _handle << " Registered." << endl;
}
}
void login(string &timeStamp,string &handle){
if (!isSystemOnline) {
return;
}
if (userbase.count(handle) == 0) {
return;
}
userType& current = userbase[handle];
if (current.isLogin) {
return;
}else{
current.isLogin = true;
cout << timeStamp << ' ' << handle << " Logined." << endl;
profile(handle);
}
}
void logoff(string &timeStamp,string &handle){
if (!isSystemOnline) {
return;
}
if (userbase.count(handle) == 0) {
return;
}
userType& current = userbase[handle];
if (!current.isLogin) {
return;
}else{
current.isLogin = false;
cout << timeStamp << ' ' << handle << " Logout." << endl;
}
}
void mkfriend(string &timeStamp,string &_handle1,string &_handle2){
if (!isSystemOnline) {
return;
}
if (_handle1 == _handle2) {
return;
}
bool exist1 = userbase.count(_handle1);
bool exist2 = userbase.count(_handle2);
if (exist1 && exist2) {
userType &usr1 = userbase[_handle1];
userType &usr2 = userbase[_handle2];
if (usr1.friendList.count(_handle2) ||
usr2.friendList.count(_handle1)) {
return;
}else{
usr1.friendList.insert(_handle2);
usr2.friendList.insert(_handle1);
msgbase.push_back(msgType(timeStamp,2,_handle1,_handle2));
usr1.msgstk.push((int)msgbase.size()-1);
usr2.msgstk.push((int)msgbase.size()-1);
cout << timeStamp << ' ' << _handle1 << " and " << _handle2 << " are now friends." << endl;
}
}else{
return;
}
}
void potwit(string &timeStamp,string &handle,string &msgBody){
if (!isSystemOnline) {
return;
}
if (userbase.count(handle) == 0) {
return;
}
userType &usr = userbase[handle];
if (usr.isLogin == false) {
return;
}
msgbase.push_back(msgType(timeStamp,1,handle,msgBody));
for (set<string>::iterator iter = usr.friendList.begin();iter != usr.friendList.end();iter++) {
userbase[*iter].msgstk.push((int)msgbase.size()-1);
}
cout << timeStamp << ' ' << handle << " said : " << msgBody << endl;
}
void refresh(string &timeStamp,string &handle){
if (!isSystemOnline) {
return;
}
if (userbase.count(handle) == 0) {
return;
}
userType &usr = userbase[handle];
if (usr.isLogin == false) {
return;
}
cout << timeStamp << ' ' << handle << " Refreshed." << endl;
profile(handle);
}
void profile(string &handle){
userType &usr = userbase[handle];
vector<int> currmsg;
int maxlen = 12+(int)handle.size();
//for (int i = usr.lastcur; i < msgbase.size(); i++) {
while (!usr.msgstk.empty()) {
int i = usr.msgstk.top();
usr.msgstk.pop();
msgType &now = msgbase[i];
if (now.type == 1) {
if (usr.friendList.count(now.arg1)) {
currmsg.push_back(i);
maxlen = max((int)(22+now.arg1.size()+now.arg2.size()),maxlen);
}
}else{
if (now.arg1 == handle) {
currmsg.push_back(i);
maxlen = max((int)(35+now.arg2.size()),maxlen);
}else if(now.arg2 == handle){
currmsg.push_back(i);
maxlen = max((int)(35+now.arg1.size()),maxlen);
}
}
}
printf("+-");
for (int i = 1; i <= maxlen; i++) {
putchar('-');
}
printf("-+\n");
printf("| User Name : ");
cout << handle;
for (int i = 1; i <= maxlen-(12+(int)handle.size()); i++) {
putchar(' ');
}
printf(" |\n");
printf("+-");
for (int i = 1; i <= maxlen; i++) {
putchar('-');
}
printf("-+\n");
if (currmsg.size()) {
for (int mi = 0; mi < currmsg.size(); mi++) {
msgType &now = msgbase[currmsg[mi]];
if (now.type == 1) {
printf("| ");
cout << now.timeStamp;
putchar(' ');
cout << now.arg1 << ' ' << "said : " << now.arg2;
for (int i = 1; i <= maxlen-(int)(22+now.arg1.size()+now.arg2.size()); i++) {
putchar(' ');
}
printf(" |");
cout << endl;
}else{
printf("| ");
cout << now.timeStamp;
putchar(' ');
if (now.arg1 == handle) {
cout << now.arg2 << " add you as a friend.";
for (int i = 1; i <= maxlen-(int)(35+now.arg2.size()); i++) {
putchar(' ');
}
}else{
cout << now.arg1 <<" add you as a friend.";
for (int i = 1; i <= maxlen-(int)(35+now.arg1.size()); i++) {
putchar(' ');
}
}
printf(" |");
cout << endl;
}
}
}
printf("+-");
for (int i = 1; i <= maxlen; i++) {
putchar('-');
}
printf("-+");
cout << endl;
}
int main(){
//freopen("sample.txt","r",stdin);
string cmd;
while (getline(cin, cmd)) {
if (cmd.size() == 0) {
continue;
}
int cur = 0;
for (; cur < cmd.size(); cur++) {
if (cmd[cur] != ' ') {
break;
}
}
string timeStamp;
for (int i = 0; i < 13; i++,cur++) {
timeStamp += cmd[cur];
}
cur++;
for (; cur < cmd.size(); cur++) {
if (cmd[cur] != ' ') {
break;
}
}
if (cmd[cur] == 'N') {
poweron(timeStamp);
continue;
}
if (cmd[cur] == 'S') {
poweroff(timeStamp);
continue;
}
string arg1;
cur++;
for (; cur < cmd.size(); cur++) {
if (cmd[cur] == '"') {
break;
}
arg1 += cmd[cur];
}
cur++;
for (; cur < cmd.size(); cur++) {
if (cmd[cur] != ' ') {
break;
}
}
if (cmd[cur] == 'R') {
cur+=2;
if (cmd[cur] == 'G') {
useradd(timeStamp, arg1);
continue;
}else if(cmd[cur] == 'F'){
refresh(timeStamp, arg1);
continue;
}
}
if (cmd[cur] == 'L') {
cur+=3;
if (cmd[cur] == 'O') {
logoff(timeStamp, arg1);
}else if(cmd[cur] == 'I'){
login(timeStamp, arg1);
}
continue;
}
if (cmd[cur] == 'A') {
cur+=3;
for (; cur < cmd.size(); cur++) {
if (cmd[cur] != ' ') {
break;
}
}
cur++;
string arg2;
for (; cur < cmd.size(); cur++) {
if (cmd[cur] == '"') {
break;
}
arg2 += cmd[cur];
}
mkfriend(timeStamp, arg1, arg2);
continue;
}
if (cmd[cur] == 'S') {
cur+=4;
for (; cur < cmd.size(); cur++) {
if (cmd[cur] != ' ') {
break;
}
}
cur++;
string arg2;
for (; cur < cmd.size(); cur++) {
if (cmd[cur] == '"') {
break;
}
arg2 += cmd[cur];
}
potwit(timeStamp, arg1, arg2);
continue;
}
}
return 0;
}