#include <iostream>
#include <string>
#include <vector>
#include <memory>

// Forward declaration
class User;

// Abstract Mediator
class ChatMediator {
public:
    virtual ~ChatMediator() = default;
    virtual void sendMessage(const std::string& msg, User* sender) = 0;
    virtual void addUser(std::shared_ptr<User> user) = 0;
};

// Abstract Colleague
class User {
protected:
    std::string name;
    ChatMediator* mediator;
public:
    User(const std::string& name, ChatMediator* med)
        : name(name), mediator(med) {}
    virtual ~User() = default;

    virtual void send(const std::string& msg) = 0;
    virtual void receive(const std::string& msg) = 0;

    const std::string& getName() const { return name; }
};

// Concrete Mediator: Chat Room
class ChatRoom : public ChatMediator {
private:
    std::vector<std::shared_ptr<User>> users;
public:
    void addUser(std::shared_ptr<User> user) override {
        users.push_back(user);
    }

    void sendMessage(const std::string& msg, User* sender) override {
        for (auto& user : users) {
            // Don't echo message back to sender
            if (user.get() != sender) {
                user->receive(msg);
            }
        }
    }
};

// Concrete Colleague: Regular User
class ChatUser : public User {
public:
    ChatUser(const std::string& name, ChatMediator* med)
        : User(name, med) {}

    void send(const std::string& msg) override {
        std::cout << name << " sends message: " << msg << std::endl;
        mediator->sendMessage(msg, this);
    }

    void receive(const std::string& msg) override {
        std::cout << name << " receives message: " << msg << std::endl;
    }
};

// Main function demo
int main() {
    // Create mediator
    auto chatRoom = std::make_shared<ChatRoom>();

    // Create users and join chat room
    auto alice = std::make_shared<ChatUser>("Alice", chatRoom.get());
    auto bob   = std::make_shared<ChatUser>("Bob", chatRoom.get());
    auto charlie = std::make_shared<ChatUser>("Charlie", chatRoom.get());

    chatRoom->addUser(alice);
    chatRoom->addUser(bob);
    chatRoom->addUser(charlie);

    std::cout << "=== Chat Start ===" << std::endl;

    alice->send("Hello everyone, I'm Alice!");
    bob->send("Hello Alice, I'm Bob.");

    std::cout << "=== Chat End ===" << std::endl;

    return 0;
}

results matching ""

    No results matching ""