/*
 * 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 (create.m_path.m_nodes.back().m_suffix.type() == typeid(listElement_))
        m_datastore.createListInstance(absolutePathFromCommand(create));
    else if (create.m_path.m_nodes.back().m_suffix.type() == typeid(leafListElement_))
        m_datastore.createLeafListInstance(absolutePathFromCommand(create));
    else
        m_datastore.createPresenceContainer(absolutePathFromCommand(create));
}

void Interpreter::operator()(const delete_& delet) const
{
    if (delet.m_path.m_nodes.back().m_suffix.type() == typeid(container_))
        m_datastore.deletePresenceContainer(absolutePathFromCommand(delet));
    else if (delet.m_path.m_nodes.back().m_suffix.type() == typeid(leafListElement_))
        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 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> {
    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 "/"s + boost::get<module_>(path).m_name + ":*";
    } else {
        auto actualPath = boost::get<boost::variant<dataPath_, schemaPath_>>(path);
        std::string pathString = boost::apply_visitor(pathToStringVisitor(), actualPath);
        auto pathScope{boost::apply_visitor(getPathScopeVisitor(), actualPath)};

        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)
{
}
