/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library
    http://www.boost.org/

    Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost
    Software License, Version 1.0. (See accompanying file
    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

#if !defined(BOOST_WAVE_LIBS_WAVE_TEST_CMD_LINE_UTILS_HPP)
#define BOOST_WAVE_LIBS_WAVE_TEST_CMD_LINE_UTILS_HPP

#include <string>
#include <fstream>
#include <vector>

#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/any.hpp>

///////////////////////////////////////////////////////////////////////////////
// forward declarations only
namespace cmd_line_utils 
{
    class include_paths;
}

namespace boost { namespace program_options 
{
    void validate(boost::any &v, std::vector<std::string> const &s,
        cmd_line_utils::include_paths *, int);
}} // boost::program_options

///////////////////////////////////////////////////////////////////////////////
#include <boost/program_options.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace cmd_line_utils {

    namespace po = boost::program_options;

    ///////////////////////////////////////////////////////////////////////////
    // Additional command line parser which interprets '@something' as an 
    // option "config-file" with the value "something".
    inline std::pair<std::string, std::string> 
    at_option_parser(std::string const& s)
    {
        if ('@' == s[0]) 
            return std::make_pair(std::string("config-file"), s.substr(1));
        else
            return std::pair<std::string, std::string>();
    }

    ///////////////////////////////////////////////////////////////////////////
    // class, which keeps the include file information read from the options
    class include_paths 
    {
    public:
        include_paths() : seen_separator(false) {}

        std::vector<std::string> paths;       // stores user paths
        std::vector<std::string> syspaths;    // stores system paths
        bool seen_separator;                  // options contain a '-I-' option

        // Function which validates additional tokens from the given option.
        static void 
        validate(boost::any &v, std::vector<std::string> const &tokens)
        {
            if (v.empty())
                v = boost::any(include_paths());

            include_paths *p = boost::any_cast<include_paths>(&v);
            BOOST_ASSERT(NULL != p);

        // Assume only one path per '-I' occurrence.
            std::string const& t = po::validators::get_single_string(tokens);
            if (t == "-") {
            // found -I- option, so switch behaviour
                p->seen_separator = true;
            } 
            else if (p->seen_separator) {
            // store this path as a system path
                p->syspaths.push_back(t); 
            } 
            else {
            // store this path as an user path
                p->paths.push_back(t);
            }            
        }
    };

    ///////////////////////////////////////////////////////////////////////////
    // Read all options from a given config string, parse and add them to the
    // given variables_map
    inline void 
    read_config_options(int debuglevel, std::string const &indata, 
        po::options_description const &desc, po::variables_map &vm)
    {
        if (9 == debuglevel) {
            std::cerr << "read_config_options: reading config options" 
                      << std::endl;
        }

        std::istringstream istrm(indata);
        
        std::vector<std::string> options;
        std::string line;

        while (std::getline(istrm, line)) {
        // skip empty lines
            std::string::size_type pos = line.find_first_not_of(" \t");
            if (pos == std::string::npos) 
                continue;

        // skip comment lines
            if ('#' != line[pos])
                options.push_back(line);
        }

        if (options.size() > 0) {
            if (9 == debuglevel) {
                std::cerr << "read_config_options: options size is: " 
                          << (int)options.size() << std::endl;
            }

            // (the (int) cast is to make the True64 compiler happy)
            using namespace boost::program_options::command_line_style;
            po::store(po::command_line_parser(options)
                .options(desc).style((int)unix_style).run(), vm);
            po::notify(vm);
        }

        if (9 == debuglevel) {
            std::cerr << "read_config_options: succeeded to read config options" 
                      << std::endl;
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // Read all options from a given config file, parse and add them to the
    // given variables_map
    inline bool
    read_config_file(int debuglevel, std::string const &filename, 
        po::options_description const &desc, po::variables_map &vm)
    {
        if (9 == debuglevel) {
            std::cerr << "read_config_file: reading config options" 
                      << std::endl;
        }

        std::ifstream ifs(filename.c_str());

        if (!ifs.is_open()) {
            std::cerr 
                << "testwave: " << filename 
                << ": command line warning: config file not found"
                << std::endl;
            return false;
        }

    // parse the file and extract all given arguments and options
        std::vector<std::string> options;
        std::string line;

        while (std::getline(ifs, line)) {
        // skip empty lines
            std::string::size_type pos = line.find_first_not_of(" \t");
            if (pos == std::string::npos) 
                continue;

        // skip comment lines
            if ('#' != line[pos]) 
                options.push_back(line);
        }

        if (options.size() > 0) {
            if (9 == debuglevel) {
                std::cerr << "read_config_file: options size is: " 
                          << (int)options.size() << std::endl;
            }

        // treat positional arguments as --input parameters
            po::positional_options_description p;
            p.add("input", -1);

        // parse the vector of lines and store the results into the given
        // variables map
            // (the (int) cast is to make the True64 compiler happy)
            using namespace boost::program_options::command_line_style;
            po::store(po::command_line_parser(options)
                .options(desc).positional(p).style((int)unix_style).run(), vm);
            po::notify(vm);
        }


        if (9 == debuglevel) {
            std::cerr << "read_config_file: succeeded to read config options" 
                      << std::endl;
        }
        return true;
    }

    ///////////////////////////////////////////////////////////////////////////
    // predicate to extract all positional arguments from the command line
    struct is_argument 
    {
        bool operator()(po::option const &opt)
        {
            return (opt.position_key == -1) ? true : false;
        }
    };

///////////////////////////////////////////////////////////////////////////////
}   // namespace cmd_line_utils

///////////////////////////////////////////////////////////////////////////////
//
//  Special validator overload, which allows to handle the -I- syntax for
//  switching the semantics of an -I option.
//
//  This must be injected into the boost::program_options namespace
//
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace program_options {

    inline void 
    validate(boost::any &v, std::vector<std::string> const &s,
        cmd_line_utils::include_paths *, int) 
    {
        cmd_line_utils::include_paths::validate(v, s);
    }

}}  // namespace boost::program_options

#endif // !defined(BOOST_WAVE_LIBS_WAVE_TEST_CMD_LINE_UTILS_HPP)
