#include <boost/algorithm/string/predicate.hpp>
#include <experimental/iterator>
#include <fstream>
#include <iostream>
#include <libyang-cpp/DataNode.hpp>
#include <libyang-cpp/Utils.hpp>
#include "UniqueResource.hpp"
#include "libyang_utils.hpp"
#include "utils.hpp"
#include "yang_access.hpp"
#include "yang_schema.hpp"

namespace {
// Convenient for functions that take m_datastore as an argument
using DatastoreType = std::optional<libyang::DataNode>;
}

YangAccess::YangAccess()
    : m_ctx(nullptr, libyang::ContextOptions::DisableSearchCwd)
    , m_datastore(std::nullopt)
    , m_schema(std::make_shared<YangSchema>(m_ctx))
{
}

YangAccess::YangAccess(std::shared_ptr<YangSchema> schema)
    : m_ctx(schema->m_context)
    , m_datastore(std::nullopt)
    , m_schema(schema)
{
}

YangAccess::~YangAccess() = default;

[[noreturn]] void YangAccess::getErrorsAndThrow() const
{
    std::vector<DatastoreError> errorsRes;

    for (const auto& err : m_ctx.getErrors()) {
        errorsRes.emplace_back(err.message, err.path);
    }
    throw DatastoreException(errorsRes);
}

void YangAccess::impl_newPath(const std::string& path, const std::optional<std::string>& value)
{
    try {
        if (m_datastore) {
            m_datastore->newPath(path.c_str(), value ? value->c_str() : nullptr, libyang::CreationOptions::Update);
        } else {
            m_datastore = m_ctx.newPath(path.c_str(), value ? value->c_str() : nullptr, libyang::CreationOptions::Update);
        }
    } catch (libyang::Error&) {
        getErrorsAndThrow();
    }
}

namespace {
void impl_unlink(DatastoreType& datastore, libyang::DataNode what)
{
    // If the node to be unlinked is the one our datastore variable points to, we need to find a new one to point to (one of its siblings)

    if (datastore == what) {
        auto oldDatastore = datastore;
        do {
            datastore = datastore->previousSibling();
            if (datastore == oldDatastore) {
                // We have gone all the way back to our original node, which means it's the only node in our
                // datastore.
                datastore = std::nullopt;
                break;
            }
        } while (datastore->schema().module().name() == "ietf-yang-library");
    }

    what.unlink();
}
}

void YangAccess::impl_removeNode(const std::string& path)
{
    if (!m_datastore) {
        // Otherwise the datastore just doesn't contain the wanted node.
        throw DatastoreException{{DatastoreError{"Datastore is empty.", path}}};
    }
    auto toRemove = m_datastore->findPath(path.c_str());
    if (!toRemove) {
        // Otherwise the datastore just doesn't contain the wanted node.
        throw DatastoreException{{DatastoreError{"Data node doesn't exist.", path}}};
    }

    impl_unlink(m_datastore, *toRemove);
}

void YangAccess::validate()
{
    if (m_datastore) {
        libyang::validateAll(m_datastore);
    }
}

DatastoreAccess::Tree YangAccess::getItems(const std::string& path) const
{
    DatastoreAccess::Tree res;
    if (!m_datastore) {
        return res;
    }

    auto set = m_datastore->findXPath(path == "/" ? "/*" : path.c_str());

    lyNodesToTree(res, set);
    return res;
}

void YangAccess::setLeaf(const std::string& path, leaf_data_ value)
{
    auto lyValue = value.type() == typeid(empty_) ? std::nullopt : std::optional(leafDataToString(value));
    impl_newPath(path, lyValue);
}

void YangAccess::createItem(const std::string& path)
{
    impl_newPath(path);
}

void YangAccess::deleteItem(const std::string& path)
{
    impl_removeNode(path);
}

namespace {
struct impl_moveItem {
    DatastoreType& m_datastore;
    libyang::DataNode m_sourceNode;

    void operator()(yang::move::Absolute absolute) const
    {
        auto set = m_sourceNode.findXPath(m_sourceNode.schema().path().get().get());
        if (set.size() == 1) { // m_sourceNode is the sole instance, do nothing
            return;
        }

        switch (absolute) {
        case yang::move::Absolute::Begin:
            if (set.front() == m_sourceNode) { // List is already at the beginning, do nothing
                return;
            }
            set.front().insertBefore(m_sourceNode);
            break;
        case yang::move::Absolute::End:
            if (set.back() == m_sourceNode) { // List is already at the end, do nothing
                return;
            }
            set.back().insertAfter(m_sourceNode);
            break;
        }
        m_datastore = m_datastore->firstSibling();
    }

    void operator()(const yang::move::Relative& relative) const
    {
        auto keySuffix = m_sourceNode.schema().nodeType() == libyang::NodeType::List ? instanceToString(relative.m_path)
                                                                    : leafDataToString(relative.m_path.at("."));
        auto destNode = m_sourceNode.findSiblingVal(m_sourceNode.schema(), keySuffix.c_str());

        if (relative.m_position == yang::move::Relative::Position::After) {
            destNode->insertAfter(m_sourceNode);
        } else {
            destNode->insertBefore(m_sourceNode);
        }
    }
};
}

void YangAccess::moveItem(const std::string& source, std::variant<yang::move::Absolute, yang::move::Relative> move)
{
    if (!m_datastore) {
        throw DatastoreException{{DatastoreError{"Datastore is empty.", source}}};
    }

    auto sourceNode = m_datastore->findPath(source.c_str());

    if (!sourceNode) {
        // The datastore doesn't contain the wanted node.
        throw DatastoreException{{DatastoreError{"Data node doesn't exist.", source}}};
    }
    std::visit(impl_moveItem{m_datastore, *sourceNode}, move);
}

void YangAccess::commitChanges()
{
    validate();
}

void YangAccess::discardChanges()
{
}

[[noreturn]] DatastoreAccess::Tree YangAccess::execute(const std::string& path, const Tree& input)
{
    auto root = [&path, this]  {
        try {
            return m_ctx.newPath(path.c_str());
        } catch (libyang::ErrorWithCode& err) {
            getErrorsAndThrow();
        }
    }();

    for (const auto& [k, v] : input) {
        if (v.type() == typeid(special_) && boost::get<special_>(v).m_value != SpecialValue::PresenceContainer) {
            continue;
        }

        try {
            root.newPath(k.c_str(), leafDataToString(v).c_str(), libyang::CreationOptions::Update);
        } catch (libyang::ErrorWithCode& err) {
            getErrorsAndThrow();
        }
    }
    throw std::logic_error("in-memory datastore doesn't support executing RPC/action");
}

void YangAccess::copyConfig(const Datastore source, const Datastore dest)
{
    if (source == Datastore::Startup && dest == Datastore::Running) {
        m_datastore = std::nullopt;
    }
}

std::shared_ptr<Schema> YangAccess::schema()
{
    return m_schema;
}

std::vector<ListInstance> YangAccess::listInstances(const std::string& path)
{
    std::vector<ListInstance> res;
    if (!m_datastore) {
        return res;
    }

    auto instances = m_datastore->findXPath(path.c_str());
    for (const auto& list : instances) {
        ListInstance instance;
        for (const auto& child : list.child()->siblings()) {
            if (child.schema().nodeType() == libyang::NodeType::Leaf) {
                auto leafSchema(child.schema().asLeaf());
                if (leafSchema.isKey()) {
                    instance.insert({std::string{leafSchema.name()}, leafValueFromNode(child.asTerm())});
                }
            }
        }
        res.emplace_back(instance);
    }
    return res;
}

std::string YangAccess::dump(const DataFormat format) const
{
    if (!m_datastore) {
        return "";
    }

    auto str = m_datastore->firstSibling().printStr(format == DataFormat::Xml ? libyang::DataFormat::XML : libyang::DataFormat::JSON, libyang::PrintFlags::WithSiblings);
    if (!str) {
        return "";
    }

    return std::string{*str};
}

void YangAccess::loadModule(const std::string& name)
{
    m_schema->loadModule(name);
}

void YangAccess::addSchemaFile(const std::string& path)
{
    m_schema->addSchemaFile(path.c_str());
}

void YangAccess::addSchemaDir(const std::string& path)
{
    m_schema->addSchemaDirectory(path.c_str());
}

void YangAccess::setEnabledFeatures(const std::string& module, const std::vector<std::string>& features)
{
    m_schema->setEnabledFeatures(module, features);
}

void YangAccess::addDataFile(const std::string& path, const StrictDataParsing strict)
{
    std::ifstream fs(path);
    char firstChar;
    fs >> firstChar;

    std::cout << "Parsing \"" << path << "\" as " << (firstChar == '{' ? "JSON" : "XML") << "...\n";

    auto dataNode = m_ctx.parseDataPath(
            path.c_str(),
            firstChar == '{' ? libyang::DataFormat::JSON : libyang::DataFormat::XML,
            strict == StrictDataParsing::Yes ? std::optional{libyang::ParseOptions::Strict} : std::nullopt,
            libyang::ValidationOptions::Present);

    if (!m_datastore) {
        m_datastore = dataNode;
    } else {
        m_datastore->merge(*dataNode);
    }

    validate();
}
