#include "binarystore.hpp"
#include "parse_config.hpp"
#include "sys_file_impl.hpp"

#include <getopt.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <stdplus/print.hpp>

constexpr auto defaultBlobConfigPath = "/usr/share/binaryblob/config.json";

struct BlobToolConfig
{
    std::string configPath = defaultBlobConfigPath;
    std::string programName;
    std::string binStore;
    std::string blobName;
    size_t offsetBytes = 0;
    enum class Action
    {
        HELP,
        LIST,
        READ,
        MIGRATE,
    } action = Action::LIST;
} toolConfig;

void printUsage(const BlobToolConfig& cfg)
{
    stdplus::print(stderr,
                   "Usage: \n"
                   "{} [OPTIONS]\n"
                   "\t--list\t\tList all supported blobs. This is a default.\n"
                   "\t--read\t\tRead blob specified in --blob argument (which "
                   "becomes mandatory).\n"
                   "\t--migrate\tUpdate all binary stores to use the alias "
                   "blob id if enabled.\n"
                   "\t--config\tFILENAME\tPath to the configuration file. The "
                   "default is /usr/share/binaryblob/config.json.\n"
                   "\t--binary-store\tFILENAME\tPath to the binary storage. If "
                   "specified, configuration file is not used.\n"
                   "\t--blob\tSTRING\tThe name of the blob to read.\n"
                   "\t--offset\tNUMBER\tThe offset in the binary store file, "
                   "where the binary store actually starts.\n"
                   "\t--help\t\tPrint this help and exit\n",
                   cfg.programName);
}

bool parseOptions(int argc, char* argv[], BlobToolConfig& cfg)
{
    cfg.programName = argv[0];

    struct option longOptions[] = {
        {"help", no_argument, 0, 'h'},
        {"list", no_argument, 0, 'l'},
        {"read", no_argument, 0, 'r'},
        {"migrate", no_argument, 0, 'm'},
        {"config", required_argument, 0, 'c'},
        {"binary-store", required_argument, 0, 's'},
        {"blob", required_argument, 0, 'b'},
        {"offset", required_argument, 0, 'g'},
        {0, 0, 0, 0},
    };

    int optionIndex = 0;
    bool res = true;
    while (1)
    {
        int ret = getopt_long_only(argc, argv, "", longOptions, &optionIndex);

        if (ret == -1)
            break;

        switch (ret)
        {
            case 'h':
                cfg.action = BlobToolConfig::Action::HELP;
                break;
            case 'l':
                cfg.action = BlobToolConfig::Action::LIST;
                break;
            case 'r':
                cfg.action = BlobToolConfig::Action::READ;
                break;
            case 'm':
                cfg.action = BlobToolConfig::Action::MIGRATE;
                break;
            case 'c':
                cfg.configPath = optarg;
                break;
            case 's':
                cfg.binStore = optarg;
                break;
            case 'b':
                cfg.blobName = optarg;
                break;
            case 'g':
                cfg.offsetBytes = std::stoi(optarg);
                break;
            default:
                res = false;
                break;
        }
    }

    return res;
}

int main(int argc, char* argv[])
{
    parseOptions(argc, argv, toolConfig);
    if (toolConfig.action == BlobToolConfig::Action::HELP)
    {
        printUsage(toolConfig);
        return 0;
    }

    std::vector<std::unique_ptr<binstore::BinaryStoreInterface>> stores;
    if (!toolConfig.binStore.empty())
    {
        auto file = std::make_unique<binstore::SysFileImpl>(
            toolConfig.binStore, toolConfig.offsetBytes);
        if (!file)
        {
            stdplus::print(stderr, "Can't open binary store {}\n",
                           toolConfig.binStore);
            printUsage(toolConfig);
            return 1;
        }

        auto store =
            binstore::BinaryStore::createFromFile(std::move(file), true);
        stores.push_back(std::move(store));
    }
    else
    {
        std::ifstream input(toolConfig.configPath);
        json j;

        if (!input.good())
        {
            stdplus::print(stderr, "Config file not found:{}\n",
                           toolConfig.configPath);
            return 1;
        }

        try
        {
            input >> j;
        }
        catch (const std::exception& e)
        {
            stdplus::print(stderr, "Failed to parse config into json:\n{}\n",
                           e.what());
            return 1;
        }

        for (const auto& element : j)
        {
            conf::BinaryBlobConfig config;
            try
            {
                conf::parseFromConfigFile(element, config);
            }
            catch (const std::exception& e)
            {
                stdplus::print(
                    stderr, "Encountered error when parsing config file:\n{}\n",
                    e.what());
                return 1;
            }

            auto file = std::make_unique<binstore::SysFileImpl>(
                config.sysFilePath, config.offsetBytes);

            auto store = binstore::BinaryStore::createFromConfig(
                config.blobBaseId, std::move(file), config.maxSizeBytes,
                config.aliasBlobBaseId);

            if (toolConfig.action == BlobToolConfig::Action::MIGRATE)
            {
                if (config.migrateToAlias && config.aliasBlobBaseId.has_value())
                {
                    store->setBaseBlobId(config.aliasBlobBaseId.value());
                }
            }
            else
            {
                stores.push_back(std::move(store));
            }
        }
    }

    if (toolConfig.action == BlobToolConfig::Action::MIGRATE)
    {
        stdplus::print(stderr,
                       "Migrated all BinaryStore back to configured Alias\n");
        return 0;
    }

    if (toolConfig.action == BlobToolConfig::Action::LIST)
    {
        stdplus::print(stderr, "Supported Blobs: \n");
        for (const auto& store : stores)
        {
            const auto blobIds = store->getBlobIds();
            std::copy(
                blobIds.begin(), blobIds.end(),
                std::ostream_iterator<decltype(blobIds[0])>(std::cout, "\n"));
        }
        return 0;
    }
    if (toolConfig.action == BlobToolConfig::Action::READ)
    {
        if (toolConfig.blobName.empty())
        {
            stdplus::print(stderr,
                           "Must specify the name of the blob to read.\n");
            printUsage(toolConfig);
            return 1;
        }

        bool blobFound = false;

        for (const auto& store : stores)
        {
            const auto blobIds = store->getBlobIds();
            if (std::any_of(blobIds.begin(), blobIds.end(),
                            [](const std::string& bn) {
                                return bn == toolConfig.blobName;
                            }))
            {
                const auto blobData = store->readBlob(toolConfig.blobName);
                if (blobData.empty())
                {
                    stdplus::print(stderr, "No data read from {}\n",
                                   store->getBaseBlobId());
                    continue;
                }

                blobFound = true;

                std::copy(
                    blobData.begin(), blobData.end(),
                    std::ostream_iterator<decltype(blobData[0])>(std::cout));

                // It's assumed that the names of the blobs are unique within
                // the system.
                break;
            }
        }

        if (!blobFound)
        {
            stdplus::print(stderr, "Blob {} not found.\n", toolConfig.blobName);
            return 1;
        }
        return 0;
    }

    return 0;
}
