/*
 * Copyright 2009- ECMWF.
 *
 * This software is licensed under the terms of the Apache Licence version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 * In applying this licence, ECMWF does not waive the privileges and immunities
 * granted to it by virtue of its status as an intergovernmental organisation
 * nor does it submit to any jurisdiction.
 */

#ifndef ecflow_viewer_CustomCommandHandler_HPP
#define ecflow_viewer_CustomCommandHandler_HPP

#include <deque>
#include <string>

class VSettings;

class CustomCommand {
public:
    CustomCommand(const std::string& name, const std::string& command, bool context);
    const std::string& name() const { return name_; }
    const std::string& command() const { return command_; }
    bool inContextMenu() const { return inContextMenu_; }
    std::string contextString() const { return (inContextMenu_ ? "yes" : "no"); }
    void set(const std::string& name, const std::string& command, bool context);
    void save(VSettings* vs) const;

private:
    std::string name_;
    std::string command_;
    bool inContextMenu_;
};

class CustomCommandHandler {
public:
    CustomCommandHandler();

    virtual CustomCommand*
    add(const std::string& name, const std::string& command, bool context, bool WriteSettings) = 0;
    CustomCommand* replace(int index, const std::string& name, const std::string& command, bool context);
    CustomCommand* replace(int index, const CustomCommand& cmd);
    CustomCommand* duplicate(int index);
    void remove(int index);
    // void remove(const std::string& name);
    // void remove(CustomCommand*);
    // CustomCommand* find(const std::string& name) const;

    // void save();
    // void save(CustomCommand*);
    void init();
    // const std::vector<NodeQuery*>& items() const {return items_;}
    CustomCommand* find(const std::string& name) const;
    int findIndexFromName(const std::string& name) const;
    int numCommands() const { return items_.size(); }
    CustomCommand* commandFromIndex(int i) { return items_[i]; };
    bool stringToBool(std::string& str);
    void swapCommandsByIndex(int i1, int i2);
    void writeSettings();

protected:
    void readSettings();
    virtual std::string settingsFile() = 0;

    const std::string suffix_;
    std::deque<CustomCommand*> items_;
};

// ----------------------------------------------------------------------------------------------
// specialisation of CustomCommandHandler to handle the commands that the user has manually saved
// ----------------------------------------------------------------------------------------------

class CustomSavedCommandHandler : public CustomCommandHandler {
public:
    CustomSavedCommandHandler() = default;
    CustomCommand* add(const std::string& name, const std::string& command, bool context, bool saveSettings) override;

    static CustomSavedCommandHandler* instance();

protected:
    static CustomSavedCommandHandler* instance_;
    std::string settingsFile() override;
};

// --------------------------------------------------------------------------------------------
// specialisation of CustomCommandHandler to handle the commands that the user has recently run
// --------------------------------------------------------------------------------------------

class CustomCommandHistoryHandler : public CustomCommandHandler {
public:
    CustomCommandHistoryHandler() = default;
    CustomCommand* add(const std::string& name, const std::string& command, bool context, bool saveSettings) override;
    static CustomCommandHistoryHandler* instance();

protected:
    static CustomCommandHistoryHandler* instance_;
    std::string settingsFile() override;
    int maxCommands_{10};
};

#endif /* ecflow_viewer_CustomCommandHandler_HPP */
