/*
 * 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 <atomic>
#include <boost/algorithm/string.hpp>
#include <docopt.h>
#include <iostream>
#include <optional>
#include <replxx.hxx>
#include <sstream>
#include "NETCONF_CLI_VERSION.h"
#include "interpreter.hpp"
#include "proxy_datastore.hpp"
#include "yang_schema.hpp"
#if defined(SYSREPO_CLI)
#include "sysrepo_access.hpp"
#define PROGRAM_NAME "sysrepo-cli"
static const auto usage = R"(CLI interface to sysrepo

Usage:
  sysrepo-cli [-d <datastore_target>]
  sysrepo-cli (-h | --help)
  sysrepo-cli --version

Options:
  -d <datastore_target>   can be "running", "startup" or "operational" [default: operational])";
#elif defined(YANG_CLI)
#include <boost/spirit/home/x3.hpp>
#include <filesystem>
#include "yang_access.hpp"
#define PROGRAM_NAME "yang-cli"
static const auto usage = R"(CLI interface for creating local YANG data instances

  The <schema_file_or_module_name> argument is treated as a file name if a file
  with such a path exists, otherwise it's treated as a module name. Search dirs
  will be used to find a schema for that module.

Usage:
  yang-cli [--configonly] [--ignore-unknown-data] [-s <search_dir>] [-e enable_features]... [-i data_file]... <schema_file_or_module_name>...
  yang-cli (-h | --help)
  yang-cli --version

Options:
  -s <search_dir>        Set search for schema lookup
  -e <enable_features>   Feature to enable after modules are loaded. This option can be supplied more than once. Format: <module_name>:<feature>
  -i <data_file>         File to import data from
  --configonly           Disable editing of operational data
  --ignore-unknown-data  Silently ignore data with no available schema file)";
#elif defined(NETCONF_CLI)
// FIXME: improve usage
static const auto usage = R"(CLI interface for NETCONF

Usage:
  netconf-cli [-v] [-d <datastore_target>] [-p <port>] <host>
  netconf-cli [-v] [-d <datastore_target>] --socket <path>
  netconf-cli (-h | --help)
  netconf-cli --version

Options:
  -v         enable verbose mode
  -p <port>  port number [default: 830]
  -d <datastore_target>   can be "running", "startup" or "operational" [default: operational])";
#include "cli-netconf.hpp"
#include "netconf_access.hpp"
#define PROGRAM_NAME "netconf-cli"
// FIXME: this should be replaced by C++20 std::jthread at some point
struct PoorMansJThread {
    ~PoorMansJThread()
    {
        if (thread.joinable()) {
            thread.join();
        }
    }
    std::thread thread;
};
#else
#error "Unknown CLI backend"
#endif

const auto HISTORY_FILE_NAME = PROGRAM_NAME "_history";

int main(int argc, char* argv[])
{
    auto args = docopt::docopt(usage,
                               {argv + 1, argv + argc},
                               true,
                               PROGRAM_NAME " " NETCONF_CLI_VERSION,
                               true);
    WritableOps writableOps = WritableOps::No;

    using replxx::Replxx;
    Replxx lineEditor;
    std::atomic<int> backendReturnCode = 0;

    // For some reason, GCC10 still needs [[maybe_unused]] because of conditional compilation...
    [[maybe_unused]] auto datastoreTarget = DatastoreTarget::Operational;
    if (const auto& ds = args["-d"]) {
        if (ds.asString() == "startup") {
            datastoreTarget = DatastoreTarget::Startup;
        } else if (ds.asString() == "running") {
            datastoreTarget = DatastoreTarget::Running;
        } else if (ds.asString() == "operational") {
            datastoreTarget = DatastoreTarget::Operational;
        } else {
            std::cerr << PROGRAM_NAME << ": unknown datastore target: " << ds.asString() << "\n";
            return 1;
        }
    }

    auto datastoreTargetString = args["-d"] ? args["-d"].asString() : std::string("operational");

#if defined(SYSREPO_CLI)
    auto datastore = std::make_shared<SysrepoAccess>();
    std::cout << "Connected to sysrepo [datastore target: " << datastoreTargetString << "]" << std::endl;
#elif defined(YANG_CLI)
    auto datastore = std::make_shared<YangAccess>();
    if (args["--configonly"].asBool()) {
        writableOps = WritableOps::No;
    } else {
        writableOps = WritableOps::Yes;
        std::cout << "ops is writable" << std::endl;
    }
    if (const auto& search_dir = args["-s"]) {
        datastore->addSchemaDir(search_dir.asString());
    }
    for (const auto& schemaFile : args["<schema_file_or_module_name>"].asStringList()) {
        if (std::filesystem::exists(schemaFile)) {
            datastore->addSchemaFile(schemaFile);
        } else if (schemaFile.find('/') == std::string::npos) { // Module names cannot have a slash
            datastore->loadModule(schemaFile);
        } else {
            std::cerr << "Cannot load YANG module " << schemaFile << "\n";
        }
    }
    if (const auto& enableFeatures = args["-e"]) {
        namespace x3 = boost::spirit::x3;
        auto grammar = +(x3::char_-":") >> ":" >> +(x3::char_-":");
        for (const auto& enableFeature : enableFeatures.asStringList()) {
            std::pair<std::string, std::string> parsed;
            auto it = enableFeature.begin();
            auto res = x3::parse(it, enableFeature.cend(), grammar, parsed);
            if (!res || it != enableFeature.cend()) {
                std::cerr << "Error parsing feature enable flags: " << enableFeature << "\n";
                return 1;
            }
            try {
                datastore->enableFeature(parsed.first, parsed.second);
            } catch (std::runtime_error& ex) {
                std::cerr << ex.what() << "\n";
                return 1;
            }
        }
    }

    auto strict = args.at("--ignore-unknown-data").asBool() ? StrictDataParsing::No : StrictDataParsing::Yes;

    if (const auto& dataFiles = args["-i"]) {
        for (const auto& dataFile : dataFiles.asStringList()) {
            datastore->addDataFile(dataFile, strict);
        }
    }
#elif defined(NETCONF_CLI)
    auto verbose = args.at("-v").asBool();
    if (verbose) {
        NetconfAccess::setNcLogLevel(NC_VERB_DEBUG);
    }

    SshProcess process;
    PoorMansJThread processWatcher;
    std::shared_ptr<NetconfAccess> datastore;

    if (args.at("--socket").asBool()) {
        try {
            datastore = std::make_shared<NetconfAccess>(args.at("<path>").asString());
        } catch (std::runtime_error& ex) {
            std::cerr << "UNIX socket connection failed: " << ex.what() << std::endl;
            return 1;
        }
    } else {
        try {
            process = sshProcess(args.at("<host>").asString(), args.at("-p").asString());
            processWatcher.thread = std::thread{std::thread{[&process, &lineEditor, &backendReturnCode] () {
                process.process.wait();
                backendReturnCode = process.process.exit_code();
                // CTRL-U clears from the cursor to the start of the line
                // CTRL-K clears from the cursor to the end of the line
                // CTRL-D send EOF
                lineEditor.emulate_key_press(replxx::Replxx::KEY::control('U'));
                lineEditor.emulate_key_press(replxx::Replxx::KEY::control('K'));
                lineEditor.emulate_key_press(replxx::Replxx::KEY::control('D'));
            }}};
            datastore = std::make_shared<NetconfAccess>(process.std_out.native_source(), process.std_in.native_sink());
        } catch (std::runtime_error& ex) {
            std::cerr << "SSH connection failed: " << ex.what() << std::endl;
            return 1;
        }
    }
    std::cout << "Connected via NETCONF [datastore target: " << datastoreTargetString << "]" << std::endl;
#else
#error "Unknown CLI backend"
#endif

    datastore->setTarget(datastoreTarget);

#if defined(SYSREPO_CLI) || defined(NETCONF_CLI)
    auto createTemporaryDatastore = [](const std::shared_ptr<DatastoreAccess>& datastore) {
        return std::make_shared<YangAccess>(std::static_pointer_cast<YangSchema>(datastore->schema()));
    };
#elif defined(YANG_CLI)
    auto createTemporaryDatastore = [](const std::shared_ptr<DatastoreAccess>&) {
        return nullptr;
    };
#endif

    ProxyDatastore proxyDatastore(datastore, createTemporaryDatastore);
    auto dataQuery = std::make_shared<DataQuery>(*datastore);
    Parser parser(datastore->schema(), writableOps, dataQuery);

    lineEditor.bind_key(Replxx::KEY::meta(Replxx::KEY::BACKSPACE), [&lineEditor](const auto& code) {
        return lineEditor.invoke(Replxx::ACTION::KILL_TO_BEGINING_OF_WORD, code);
    });
    lineEditor.bind_key(Replxx::KEY::control('W'), [&lineEditor](const auto& code) {
        return lineEditor.invoke(Replxx::ACTION::KILL_TO_WHITESPACE_ON_LEFT, code);
    });

    lineEditor.set_word_break_characters("\t _[]/:'\"=-%");

    lineEditor.set_completion_callback([&parser](const std::string& input, int& context) {
        std::stringstream stream;
        Completions completions;
        try {
            completions = parser.completeCommand(input, stream);
        } catch (std::exception& ex) {
            std::cerr << "Error while completing: " << ex.what() << "\n";
        }

        std::vector<replxx::Replxx::Completion> res;
        std::copy(completions.m_completions.begin(), completions.m_completions.end(), std::back_inserter(res));
        context = completions.m_contextLength;
        return res;
    });

    std::optional<std::string> historyFile;
    if (auto xdgHome = getenv("XDG_DATA_HOME")) {
        historyFile = std::string(xdgHome) + "/" + HISTORY_FILE_NAME;
    } else if (auto home = getenv("HOME")) {
        historyFile = std::string(home) + "/.local/share/" + HISTORY_FILE_NAME;
    }

    if (historyFile) {
        lineEditor.history_load(historyFile.value());
    }

    while (backendReturnCode == 0) {
        auto fullContextPath = parser.currentNode();
        std::string prompt;
        if (auto activeRpcPath = proxyDatastore.inputDatastorePath()) {
            auto rpcPrefixLength = activeRpcPath->size();
            prompt = "(prepare: " + *activeRpcPath + ") " + fullContextPath.substr(rpcPrefixLength);
        } else {
            prompt = fullContextPath;
        }

        prompt += "> ";

        auto line = lineEditor.input(prompt);
        if (!line) {
            // If user pressed CTRL-C to abort the line, errno gets set to EAGAIN.
            // If user pressed CTRL-D (for EOF), errno doesn't get set to EAGAIN, so we exit the program.
            // I have no idea why replxx uses errno for this.
            if (errno == EAGAIN) {
                continue;
            } else {
                break;
            }
        }

        std::locale C_locale("C");
        std::string_view view{line};
        if (std::all_of(view.begin(), view.end(),
                        [C_locale](const auto c) { return std::isspace(c, C_locale);})) {
            continue;
        }

        try {
            command_ cmd = parser.parseCommand(line, std::cout);
            boost::apply_visitor(Interpreter(parser, proxyDatastore), cmd);
        } catch (InvalidCommandException& ex) {
            std::cerr << ex.what() << std::endl;
        } catch (DatastoreException& ex) {
            std::cerr << ex.what() << std::endl;
        } catch (std::runtime_error& ex) {
            std::cerr << ex.what() << std::endl;
        } catch (std::logic_error& ex) {
            std::cerr << ex.what() << std::endl;
        }

        lineEditor.history_add(line);
    }

    if (historyFile) {
        lineEditor.history_save(historyFile.value());
    }

    return backendReturnCode;
}
