#ifndef WorkerSubprocess_hpp
#define WorkerSubprocess_hpp

#include <JuceHeader.h>
#include "properties.h"
#include <chrono>

inline void loadPluginLists(std::map<std::string, std::unique_ptr<juce::KnownPluginList>> & lists) {
    lists.clear();
    auto savedPluginLists = getAppProperties().getUserSettings()->getXmlValue("pluginLists");
    
    if(!savedPluginLists) {
        return;
    }
    
    for(auto * child : savedPluginLists->getChildIterator()) {
        auto arch = child->getStringAttribute("architecture");
        auto spl = child->getFirstChildElement();
        if(!spl) {
            continue;
        }
        auto lst = std::make_unique<juce::KnownPluginList>();
        lst->recreateFromXml(*spl);
        lists.insert(std::make_pair(arch.toStdString(), std::move(lst)));
    }
}

inline void savePluginLists(const std::map<std::string, std::unique_ptr<juce::KnownPluginList>> & lists) {
    auto elem = std::make_unique<juce::XmlElement>("PluginLists");
    for(auto & p : lists) {
        auto childElem = std::make_unique<juce::XmlElement>("PluginListByArchitecture");
        childElem->setAttribute("architecture", p.first);
        auto lstXml = p.second->createXml();
        childElem->addChildElement(lstXml.release());
        elem->addChildElement(childElem.release());
    }
    getAppProperties().getUserSettings()->setValue("pluginLists", elem.get());
    getAppProperties().getUserSettings()->saveIfNeeded();
}

inline void clearSavedPluginLists() {
    getAppProperties().getUserSettings()->removeValue("pluginLists");
    getAppProperties().getUserSettings()->saveIfNeeded();
}

class WebsocketThread;

class WorkerSubprocess final : public juce::ChildProcessWorker, private juce::AsyncUpdater, private juce::Timer
{
public:
    WorkerSubprocess();
    ~WorkerSubprocess();

    bool initialiseFromCommandLine (const juce::String& commandLine,
                                    const juce::String& commandLineUniqueID,
                                    int timeoutMs = 0);

    void handleMessageFromCoordinator (const juce::MemoryBlock& mb) override;
    void handleConnectionLost() override;
    void handleAsyncUpdate() override;
    void timerCallback() override;
    

    // isLaunching == true will keep all editor windows open
    // on windows: true while the window is launching, false otherwise
    // on mac: is set to the value of Process::isForegroundProcess() by polling
    void updateLaunching(bool isLaunching);
    void startup(std::unique_ptr<juce::XmlElement> startupArgs);
    
private:
    std::unique_ptr<WebsocketThread> workerThread;
    std::chrono::steady_clock::time_point startTime;
    std::atomic<bool> timeoutArmed;
    std::atomic<bool> lastForegroundMessage;
    bool shuttingDown;
};

#endif /* WorkerSubprocess_hpp */
