/*
 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
 *
 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
 *
*/

#include <boost/algorithm/string/predicate.hpp>
#include <boost/mpl/for_each.hpp>
#include <iostream>
#include <sstream>
#include "datastore_access.hpp"
#include "interpreter.hpp"
#include "utils.hpp"

void Interpreter::operator()(const commit_&) const
{
    m_datastore.commitChanges();
}

void Interpreter::operator()(const discard_&) const
{
    m_datastore.discardChanges();
}

void Interpreter::operator()(const set_& set) const
{
    auto data = set.m_data;

    // If the user didn't supply a module prefix for identityref, we need to add it ourselves
    if (data.type() == typeid(identityRef_)) {
        auto identityRef = boost::get<identityRef_>(data);
        if (!identityRef.m_prefix) {
            identityRef.m_prefix = set.m_path.m_nodes.front().m_prefix.value();
            data = identityRef;
        }
    }
    m_datastore.setLeaf(absolutePathFromCommand(set), data);
}

void Interpreter::operator()(const get_& get) const
{
    auto items = m_datastore.getItems(absolutePathFromCommand(get));
    for (auto it = items.begin(); it != items.end(); it++) {
        auto [path, value] = *it;
        if (value.type() == typeid(special_) && boost::get<special_>(value).m_value == SpecialValue::LeafList) {
            auto leafListPrefix = path;
            std::cout << path << " = " << leafDataToString(value) << std::endl;
            ++it;
            while (boost::starts_with(it->first, leafListPrefix)) {
                std::cout << stripLeafListValueFromPath(it->first) << " = " << leafDataToString(it->second) << std::endl;
                ++it;
            }
        } else {
            std::cout << path << " = " << leafDataToString(value) << std::endl;
        }
    }
}

void Interpreter::operator()(const cd_& cd) const
{
    m_parser.changeNode(cd.m_path);
}

void Interpreter::operator()(const create_& create) const
{
    if (std::holds_alternative<listElement_>(create.m_path.m_nodes.back().m_suffix))
        m_datastore.createListInstance(absolutePathFromCommand(create));
    else if (std::holds_alternative<leafListElement_>(create.m_path.m_nodes.back().m_suffix))
        m_datastore.createLeafListInstance(absolutePathFromCommand(create));
    else
        m_datastore.createPresenceContainer(absolutePathFromCommand(create));
}

void Interpreter::operator()(const delete_& delet) const
{
    if (std::holds_alternative<container_>(delet.m_path.m_nodes.back().m_suffix))
        m_datastore.deletePresenceContainer(absolutePathFromCommand(delet));
    else if (std::holds_alternative<leafListElement_>(delet.m_path.m_nodes.back().m_suffix))
        m_datastore.deleteLeafListInstance(absolutePathFromCommand(delet));
    else
        m_datastore.deleteListInstance(absolutePathFromCommand(delet));
}

void Interpreter::operator()(const ls_& ls) const
{
    std::cout << "Possible nodes:" << std::endl;
    auto recursion{Recursion::NonRecursive};
    for (auto it : ls.m_options) {
        if (it == LsOption::Recursive)
            recursion = Recursion::Recursive;
    }

    std::set<ModuleNodePair> toPrint;

    auto pathArg = dataPathToSchemaPath(m_parser.currentPath());
    if (ls.m_path) {
        if (ls.m_path->type() == typeid(module_)) {
            toPrint = m_datastore.schema()->availableNodes(*ls.m_path, recursion);
        } else {
            auto schemaPath = anyPathToSchemaPath(*ls.m_path);
            if (schemaPath.m_scope == Scope::Absolute) {
                pathArg = schemaPath;
            } else {
                pathArg.m_nodes.insert(pathArg.m_nodes.end(), schemaPath.m_nodes.begin(), schemaPath.m_nodes.end());
            }
            toPrint = m_datastore.schema()->availableNodes(pathArg, recursion);
        }
    } else {
        toPrint = m_datastore.schema()->availableNodes(pathArg, recursion);
    }

    for (const auto& it : toPrint) {
        std::cout << (it.first ? *it.first + ":" : "" ) + it.second << std::endl;
    }
}

void Interpreter::operator()(const copy_& copy) const
{
    m_datastore.copyConfig(copy.m_source, copy.m_destination);
}

std::string Interpreter::buildTypeInfo(const std::string& path) const
{
    std::ostringstream ss;
    switch (m_datastore.schema()->nodeType(path)) {
    case yang::NodeTypes::Container:
        ss << "container";
        break;
    case yang::NodeTypes::PresenceContainer:
        ss << "presence container";
        break;
    case yang::NodeTypes::Leaf:
    {
        auto leafType = m_datastore.schema()->leafType(path);
        auto typedefName = m_datastore.schema()->leafTypeName(path);
        std::string baseTypeStr;
        if (std::holds_alternative<yang::LeafRef>(leafType.m_type)) {
            ss << "-> ";
            ss << m_datastore.schema()->leafrefPath(path) << " ";
            baseTypeStr = leafDataTypeToString(std::get<yang::LeafRef>(leafType.m_type).m_targetType->m_type);
        } else {
            baseTypeStr = leafDataTypeToString(leafType.m_type);
        }

        if (typedefName) {
            ss << *typedefName << " (" << baseTypeStr << ")";
        } else {
            ss << baseTypeStr;
        }

        if (leafType.m_units) {
            ss << " [" + *leafType.m_units + "]";
        }

        if (m_datastore.schema()->leafIsKey(path)) {
            ss << " (key)";
        }

        if (auto defaultValue = m_datastore.schema()->defaultValue(path)) {
            ss << " default: " << leafDataToString(*defaultValue);
        }
        break;
    }
    case yang::NodeTypes::List:
        ss << "list";
        break;
    case yang::NodeTypes::Action:
    case yang::NodeTypes::AnyXml:
    case yang::NodeTypes::LeafList:
    case yang::NodeTypes::Notification:
    case yang::NodeTypes::Rpc:
        throw std::logic_error("describe got an rpc or an action: this should never happen, because their paths cannot be parsed");
    }

    if (!m_datastore.schema()->isConfig(path)) {
        ss << " (ro)";
    }

    return ss.str();
}

void Interpreter::operator()(const describe_& describe) const
{
    auto path = absolutePathFromCommand(describe);
    auto status = m_datastore.schema()->status(path);
    auto statusStr = status == yang::Status::Deprecated ? " (deprecated)" :
        status == yang::Status::Obsolete ? " (obsolete)" :
        "";

    std::cout << path << ": " << buildTypeInfo(path) << statusStr << std::endl;
    if (auto description = m_datastore.schema()->description(path)) {
        std::cout << std::endl << *description << std::endl;
    }
}

struct commandLongHelpVisitor : boost::static_visitor<const char*> {
    template <typename T>
    auto constexpr operator()(boost::type<T>) const
    {
        return T::longHelp;
    }
};

struct commandShortHelpVisitor : boost::static_visitor<const char*> {
    template <typename T>
    auto constexpr operator()(boost::type<T>) const
    {
        return T::shortHelp;
    }
};

void Interpreter::operator()(const help_& help) const
{
    if (help.m_cmd)
        std::cout << boost::apply_visitor(commandLongHelpVisitor(), help.m_cmd.get()) << std::endl;
    else
        boost::mpl::for_each<CommandTypes, boost::type<boost::mpl::_>>([](auto cmd) {
            std::cout << commandShortHelpVisitor()(cmd) << std::endl;
        });
}

template <typename T>
std::string Interpreter::absolutePathFromCommand(const T& command) const
{
    if (command.m_path.m_scope == Scope::Absolute)
        return pathToDataString(command.m_path, Prefixes::WhenNeeded);
    else
        return joinPaths(m_parser.currentNode(), pathToDataString(command.m_path, Prefixes::WhenNeeded));
}

struct pathToStringVisitor : boost::static_visitor<std::string> {
    std::string operator()(const module_& path) const
    {
        using namespace std::string_literals;
        return "/"s + boost::get<module_>(path).m_name + ":*";
    }
    std::string operator()(const schemaPath_& path) const
    {
        return pathToSchemaString(path, Prefixes::WhenNeeded);
    }
    std::string operator()(const dataPath_& path) const
    {
        return pathToDataString(path, Prefixes::WhenNeeded);
    }
};

struct getPathScopeVisitor : boost::static_visitor<Scope> {
    Scope operator()(const module_&) const
    {
        throw std::logic_error("Interpreter: a top-level module has no scope.");
    }

    template <typename T>
    Scope operator()(const T& path) const
    {
        return path.m_scope;
    }
};

std::string Interpreter::absolutePathFromCommand(const get_& get) const
{
    using namespace std::string_literals;
    if (!get.m_path) {
        return m_parser.currentNode();
    }

    const auto path = *get.m_path;
    if (path.type() == typeid(module_)) {
        return boost::apply_visitor(pathToStringVisitor(), path);
    } else {
        std::string pathString = boost::apply_visitor(pathToStringVisitor(), path);
        auto pathScope{boost::apply_visitor(getPathScopeVisitor(), path)};

        if (pathScope == Scope::Absolute) {
            return pathString;
        } else {
            return joinPaths(m_parser.currentNode(), pathString);
        }
    }
}

std::string Interpreter::absolutePathFromCommand(const describe_& describe) const
{
    auto pathStr = boost::apply_visitor(pathToStringVisitor(), describe.m_path);
    if (boost::apply_visitor(getPathScopeVisitor(), describe.m_path) == Scope::Absolute)
        return pathStr;
    else
        return joinPaths(m_parser.currentNode(), pathStr);
}

Interpreter::Interpreter(Parser& parser, DatastoreAccess& datastore)
    : m_parser(parser)
    , m_datastore(datastore)
{
}
