#include <sstream>

#include "option_set.h"
#include "argtype_registry.h"
#include "util.h"

Option_set::Option_set(
    const std::string& name, const std::string& desc,
    const Parameter_set& parameters, const katom_lists& members, const Locator& loc)
    : m_name(name)
    , m_desc(desc)
    , m_parameters(parameters)
    , m_members(members)
    , m_loc(loc)
{}

const Parameter* Option_set::find(const std::string& name) const
{
    for (const Parameter& p : m_parameters.m_optional) {
        if (p.m_name == name) {
            return &p;
        }
    }
    return nullptr;
}

std::string Option_set::member_names() const
{
    std::vector<std::string> names {};
    for (const Parameter& p : m_parameters.m_optional) {
        names.push_back(":" + p.m_name);
    }
    return join(names, " ");
}

// One member per line: the name, its type, and its default -- the same three
// things a klammer's signature shows, since that is what the using klammer
// ends up declaring.
std::string Option_set::describe(int margin) const
{
    std::string tab(margin, ' ');
    std::stringstream ss {};
    ss << tab << "@@" << m_name << ".o\n";
    for (const Parameter& p : m_parameters.m_optional) {
        std::string line = ":" + p.m_name;
        if (p.m_argtype.m_name != default_argtype) {
            line += "." + p.m_argtype.m_name;
        }
        if (!p.m_default.empty()) {
            line += " " + p.m_default;
            if (p.m_default_from_type) {
                line += "  (from the " + p.m_argtype.m_name + " argument type)";
            }
        }
        ss << tab << "  " << line << "\n";
    }
    if (!m_desc.empty()) {
        ss << justify(m_desc, 80, margin + 2) << "\n";
    }
    if (!m_users.empty()) {
        ss << tab << "  Used by: " << join(m_users, ", ") << "\n";
    }
    return ss.str();
}
