#ifndef INCLUDED_OPTIONS_
#define INCLUDED_OPTIONS_

#include <memory>
#include <unordered_map>

#include <bobcat/argconfig>
#include <bobcat/log>
#include <bobcat/multibuf>
#include <bobcat/syslogstream>

#include "../udsreq/udsreq.h"

namespace FBB
{
    class SyslogStream;
}

class Options: public UDSReq
{
    using FacilityMap = std::unordered_map<std::string, FBB::Facility>;
    using PriorityMap = std::unordered_map<std::string, FBB::Priority>;

    FBB::ArgConfig &d_arg;

    std::unique_ptr<FBB::SyslogStream> d_syslog;
    FBB::Log d_log;

    FBB::MultiBuf d_multiBuf;
    std::string d_cronFile;                  // canonical d_arg[0]
    std::ostream d_msg;                     // d_msg handles all messages to
                                            // syslog and/or d_log

    std::string d_agent;
    std::string d_mailer;
    std::string d_uds;                      // e.g., ~/.ssh-cron.uds

    FacilityMap::const_iterator d_syslogFacility;
    PriorityMap::const_iterator d_syslogPriority;

    bool d_foreground;
    bool d_list;
    bool d_reload;
    bool d_terminate;

    Req d_udsReq;           // requests received via the UDS

    static std::unique_ptr<Options> s_options;

    static FBB::Facility    s_defaultSyslogFacility;
    static FBB::Priority    s_defaultSyslogPriority;
    static char const       s_defaultAgent[];
    static char const       s_defaultConfigFile[];
    static char const       s_defaultUDS[];
    static char const       s_defaultSyslogIdent[];
    static char const       s_defaultMailer[];

    static FacilityMap const s_syslogFacilities;
    static PriorityMap const s_syslogPriorities;

    public:
        static Options &instance();

        Options(Options const &other) = delete;

        size_t nArgs() const;                                           // .f
        char const *arg(size_t idx) const;                              // .f
        std::string const &cronFile() const;                            // .f
        bool foreground() const;                                        // .f
        bool daemon() const;                                            // .f
        bool cronCmd() const;      // e.g., --list, --terminate    // .f
        bool reload() const;                                            // .f
        std::string const &basename() const;                            // .f
        std::string const &mailer() const;
        std::ostream &msg();                                            // .f
        std::string const &uds() const;                                 // .f
        Req request() const;                                            // .f

        static char const *defaultAgent();                              // .f
        static char const *defaultConfigFile();                         // .f
        static char const *defaultMailer();                             // .f
        static char const *defaultSyslogIdent();                        // .f
        static FBB::Facility defaultSyslogFacility();                   // .f
        static FBB::Priority defaultSyslogPriority();                   // .f
        static char const *defaultUDS();                                // .f

    private:
        Options();

        bool setSyslog();

        void checkAction() const;
        void loadConfigFile();

        std::string syslogTag() const;
        FBB::Priority syslogPriority() const;
        FBB::Facility syslogFacility() const;
};

#include "options.f"

#endif





