// Copyright Vladimir Prus 2002-2004.
// 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)


#define BOOST_PROGRAM_OPTIONS_SOURCE
#include <boost/program_options/config.hpp>

#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/errors.hpp>
#include <boost/program_options/detail/convert.hpp>
#include <boost/throw_exception.hpp>

#include <iostream>
#include <fstream>
#include <cassert>

namespace boost { namespace program_options { namespace detail {

    using namespace std;

    common_config_file_iterator::common_config_file_iterator(
        const std::set<std::string>& allowed_options,
        bool allow_unregistered)
    : allowed_options(allowed_options),
      m_allow_unregistered(allow_unregistered)
    {
        for(std::set<std::string>::const_iterator i = allowed_options.begin();
            i != allowed_options.end(); 
            ++i)
        {
            add_option(i->c_str());
        }
    }

    void
    common_config_file_iterator::add_option(const char* name)
    {
        string s(name);
        assert(!s.empty());
        if (*s.rbegin() == '*') {
            s.resize(s.size()-1);
            bool bad_prefixes(false);
            // If 's' is a prefix of one of allowed suffix, then
            // lower_bound will return that element.
            // If some element is prefix of 's', then lower_bound will
            // return the next element.
            set<string>::iterator i = allowed_prefixes.lower_bound(s);
            if (i != allowed_prefixes.end()) {
                if (i->find(s) == 0)
                    bad_prefixes = true;                    
            }
            if (i != allowed_prefixes.begin()) {
                --i;
                if (s.find(*i) == 0)
                    bad_prefixes = true;
            }
            if (bad_prefixes)
                boost::throw_exception(error("bad prefixes"));
            allowed_prefixes.insert(s);
        }
    }

    namespace {
        string trim_ws(const string& s)
        {
            string::size_type n, n2;
            n = s.find_first_not_of(" \t\r\n");
            if (n == string::npos)
                return string();
            else {
                n2 = s.find_last_not_of(" \t\r\n");
                return s.substr(n, n2-n+1);
            }
        }
    }


    void common_config_file_iterator::get()
    {
        string s;
        string::size_type n;
        bool found = false;

        while(this->getline(s)) {

            // strip '#' comments and whitespace
            if ((n = s.find('#')) != string::npos)
                s = s.substr(0, n);
            s = trim_ws(s);

            if (!s.empty()) {
                // Handle section name
                if (*s.begin() == '[' && *s.rbegin() == ']') {
                    m_prefix = s.substr(1, s.size()-2);
                    if (*m_prefix.rbegin() != '.')
                        m_prefix += '.';
                }
                else if ((n = s.find('=')) != string::npos) {

                    string name = m_prefix + trim_ws(s.substr(0, n));
                    string value = trim_ws(s.substr(n+1));

                    bool registered = allowed_option(name);
                    if (!registered && !m_allow_unregistered)
                        boost::throw_exception(unknown_option(name));

                    found = true;
                    this->value().string_key = name;
                    this->value().value.clear();
                    this->value().value.push_back(value);
                    this->value().unregistered = !registered;
                    this->value().original_tokens.clear();
                    this->value().original_tokens.push_back(name);
                    this->value().original_tokens.push_back(value);
                    break;

                } else {
                    boost::throw_exception(invalid_syntax(s, invalid_syntax::unrecognized_line));
                }
            }
        }
        if (!found)
            found_eof();
    }


    bool 
    common_config_file_iterator::allowed_option(const std::string& s) const
    {
        set<string>::const_iterator i = allowed_options.find(s);
        if (i != allowed_options.end())
            return true;        
        // If s is "pa" where "p" is allowed prefix then
        // lower_bound should find the element after "p". 
        // This depends on 'allowed_prefixes' invariant.
        i = allowed_prefixes.lower_bound(s);
        if (i != allowed_prefixes.begin() && s.find(*--i) == 0)
            return true;
        return false;
    }

#if BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4303)) || \
        (defined(__sgi) && BOOST_WORKAROUND(_COMPILER_VERSION, BOOST_TESTED_AT(741)))
    template<>
    bool
    basic_config_file_iterator<wchar_t>::getline(std::string& s)
    {
        std::wstring ws;
        // On Comeau, using two-argument version causes
        // call to some internal function with std::wstring, and '\n'
        // (not L'\n') and compile can't resolve that call.

        if (std::getline(*is, ws, L'\n')) {
            s = to_utf8(ws);
            return true;
        } else {
            return false;
        }            
    }
#endif    

}}}

#if 0
using boost::program_options::config_file;

#include <sstream>
#include <cassert>

int main()
{
    try {
        stringstream s(
            "a = 1\n"
            "b = 2\n");

        config_file cf(s);
        cf.add_option("a");
        cf.add_option("b");

        assert(++cf);
        assert(cf.name() == "a");
        assert(cf.value() == "1");
        assert(++cf);
        assert(cf.name() == "b");
        assert(cf.value() == "2");
        assert(!++cf);
    }
    catch(exception& e)
    {
        cout << e.what() << "\n";
    }
}
#endif
