#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(std::nullopt, libyang::ContextOptions::DisableSearchCwd | libyang::ContextOptions::SetPrivParsed)
    , 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, value, libyang::CreationOptions::Update);
        } else {
            m_datastore = m_ctx.newPath(path, value, 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);
    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);

    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());
        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);

        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);

    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);
        } 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, leafDataToString(v), 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);
    for (const auto& list : instances) {
        ListInstance instance;
        for (const auto& child : list.immediateChildren()) {
            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.parseData(
            std::filesystem::path{path},
            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();
}
