#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <memory>
#include <vector>

class Browser {
public:
    struct Observer {
        virtual ~Observer() = default;
        virtual void browserAboutToQuit() = 0;
        virtual void browserFocusChanged() = 0;
    };

    ~Browser() {
        std::cout << "Browser is closing\n";
        notifyOnQuit();
        std::cout << "Browser closed\n";
    }
    // Rule of 5 :)

    void attach(Observer* observer) { _observers.push_back(observer); }
    void detach(Observer* observer) { std::erase(_observers, observer); }

private:
    void notifyOnQuit() const {
        std::ranges::for_each(_observers, std::mem_fn(&Observer::browserAboutToQuit));
    }
    void notifyOnFocusChanfed() const {
        std::ranges::for_each(_observers, std::mem_fn(&Observer::browserFocusChanged));
    }

    std::vector<Observer*> _observers;
};

class TabStripManager : public Browser::Observer {
public:
    TabStripManager(Browser* browser)
        : _browser(browser) {
        assert(browser);
        browser->attach(this);
    }

    ~TabStripManager() {
        if (_browser) {
            _browser->detach(this);
        }
    }
    // Rule of 5 :)

    void browserAboutToQuit() override {
        std::cout << "TabStripManager will close tabs\n";
        _browser = nullptr;
    }

    void browserFocusChanged() override {
        std::cout << "TabStripManager lost focus\n";
    }

private:
    Browser* _browser;
};

int main() {
    std::unique_ptr<Browser> browser = std::make_unique<Browser>();
    TabStripManager manager(browser.get());
    browser = nullptr;
}