#ifndef INCLUDED_OPTIONS_
#define INCLUDED_OPTIONS_

#include <fstream>
#include <string>
#include <memory>

#include <bobcat/argconfig>

#include "../enums/enums.h"

namespace std
{
    class error_code;
}

namespace FBB
{
    class LogBuf;
    class SyslogBuf;
}

class Options
{
    FBB::ArgConfig &d_arg;

    bool d_inspect;
    bool d_cls;
    std::string d_received;

    std::string d_expire;
    bool d_interactive;
    std::string d_logSpec;

    std::string d_ip4;

    bool d_logIgnored[eActionSize];         // true if mail hdrs are logged
    std::unique_ptr<std::ofstream> d_mailFile[eActionSize];
    std::unique_ptr<std::ifstream> d_rules;


                                                        // used for logging:
                                                        // stream written when
    std::unique_ptr<std::ofstream>   d_outStreamPtr;    // logging to file

                                                        // log-buffer passed to
    std::unique_ptr<FBB::LogBuf>    d_logBufPtr;        // d_outPtr's stream

    std::unique_ptr<FBB::SyslogBuf> d_syslogBufPtr;

    std::unique_ptr<std::ostream>   d_logPtr;

    bool d_preamble;                                    // test specifications
    bool d_syntax;

    static std::string s_accept;                        // values are defined
    static char const *s_action[][2];
    static std::string s_base;                          // in data.cc
    static char const s_configFile[];
    static std::string s_configDir;  // the path to the config dir, ends in /
    static std::error_code s_ec;
    static std::string s_ip4;
    static std::unique_ptr<Options> s_optionsPtr;

    public:
        static void initialize(void (*usage)(std::string const &),
                                   char const *version, FBB::ArgConfig &arg);
        static Options &instance();

        bool cls() const;                                               // .f
        std::string const &received() const;                            // .f

        std::string const &expire() const;                              // .f
        bool interactive() const;                                       // .f
        bool logIgnored(eAction type) const;                            // .f
        std::ostream *logPtr() const;                                   // .f
        std::ofstream *mailFile(eAction type) const;                    // .f
        bool preamble() const;                                          // .f
        void preambleOnly() const;
        std::ifstream rulesStream();                                    // .f
        bool syntax() const;                                            // .f
        std::string const &ip4() const;                                 // .f
        auto beginEndRE(std::string const &target);                     // .f

        static char const *mailType(eAction type);                      // .f
        static void setBase(std::string &path);

    private:
        Options(void (*usage)(std::string const &),
                char const *version, FBB::ArgConfig &arg);

        void configFile();
        bool expiration();
        bool inspect();
        void mailFiles();
        void rulesFile();
        void logFile();

        void setBase();

        void useLogFile(std::string const &spec);
        void useSyslog(std::string const &spec);
};

#include "options.f"
        
#endif
