//
//  Copyright (C) 2016  Clifford Wolf <clifford@clifford.at>
//  Copyright (C) 2019  Sylvain Munaut <tnt@246tNt.com>
//
//  Permission to use, copy, modify, and/or distribute this software for any
//  purpose with or without fee is hereby granted, provided that the above
//  copyright notice and this permission notice appear in all copies.
//
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
//  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
//  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
//  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
//  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
//  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#ifdef _WIN32
#define NOMINMAX
#include "Windows.h"
#undef NOMINMAX
#else
#include <unistd.h>
#include <sys/time.h>
#endif

#include <map>
#include <vector>
#include <string>
#include <fstream>
#include <iostream>

#include <boost/program_options.hpp>

#include "ChipConfig.hpp"
#include "Chip.hpp"
#include "Database.hpp"
#include "DatabasePath.hpp"

using std::map;
using std::pair;
using std::vector;
using std::string;
using std::ifstream;
using std::getline;

uint64_t x;
uint64_t xorshift64star(void) {
    x ^= x >> 12; // a
    x ^= x << 25; // b
    x ^= x >> 27; // c
    return x * UINT64_C(2685821657736338717);
}

void push_back_bitvector(vector<vector<bool>> &hexfile, const vector<int> &digits)
{
    if (digits.empty())
        return;

    hexfile.push_back(vector<bool>(digits.size() * 4));

    for (int i = 0; i < int(digits.size()) * 4; i++)
        if ((digits.at(digits.size() - i/4 -1) & (1 << (i%4))) != 0)
            hexfile.back().at(i) = true;
}

void parse_hexfile_line(const char *filename, int linenr, vector<vector<bool>> &hexfile, string &line)
{
    vector<int> digits;

    for (char c : line) {
        if ('0' <= c && c <= '9')
            digits.push_back(c - '0');
        else if ('a' <= c && c <= 'f')
            digits.push_back(10 + c - 'a');
        else if ('A' <= c && c <= 'F')
            digits.push_back(10 + c - 'A');
        else if ('x' == c || 'X' == c ||
             'z' == c || 'Z' == c)
            digits.push_back(0);
        else if ('_' == c)
            ;
        else if (' ' == c || '\t' == c || '\r' == c) {
            push_back_bitvector(hexfile, digits);
            digits.clear();
        } else goto error;
    }

    push_back_bitvector(hexfile, digits);

    return;

error:
    fprintf(stderr, "Can't parse line %d of %s: %s\n", linenr, filename, line.c_str());
    exit(1);
}

int main(int argc, char **argv)
{
    bool verbose = false;
#ifdef _WIN32
    uint32_t seed_nr = GetCurrentProcessId();
#else
    uint32_t seed_nr = getpid();
#endif
    namespace po = boost::program_options;

    std::string database_folder = get_database_path();;

    po::options_description options("Allowed options");

    po::options_description options_any("Generic options");
    options_any.add_options()("help,h", "show help");
    options_any.add_options()("verbose,v", "verbose output");

    po::options_description options_init("Initialize options");
    options_init.add_options()("input,i", po::value<std::string>(), "input configuration file");
    options_init.add_options()("output,o", po::value<std::string>(), "output configuration file");
    options_init.add_options()("from,f", po::value<std::string>(), "original content hex file");
    options_init.add_options()("to,t", po::value<std::string>(), "new content hex file");

    po::options_description options_gen("Generate options");
    options_gen.add_options()("generate,g", po::value<std::string>(), "Generate random hex of given geometry into given file");
    options_gen.add_options()("seed,s", po::value<int>(), "seed random generator with fixed value");
    options_gen.add_options()("width,w", po::value<int>(), "width of the BRAM content (in bits)");
    options_gen.add_options()("depth,d", po::value<int>(), "idepth of the BRAM content (in # of words)");

    options.add(options_any).add(options_init).add(options_gen);

    po::variables_map vm;
    try {
        po::parsed_options parsed = po::command_line_parser(argc, argv).options(options).run();
        po::store(parsed, vm);
        po::notify(vm);
    }
    catch (std::exception &e) {
        cerr << e.what() << endl << endl;
        goto help;
    }

    if (vm.count("help")) {
    help:
        cerr << "Project Trellis - Open Source Tools for ECP5 FPGAs" << endl;
        cerr << "ecpbram: ECP5 BRAM content initialization tool" << endl;
        cerr << endl;
        cerr << "Copyright (C) 2019  Sylvain Munaut <tnt@246tNt.com>" << endl;
        cerr << "Copyright (C) 2016  Clifford Wolf <clifford@clifford.at>" << endl;
        cerr << endl;
        cerr << options << endl;
        return vm.count("help") ? 0 : 1;
    }

    if (vm.count("verbose"))
        verbose = true;

    if (vm.count("generate"))
    {
        if (!vm.count("width") || !vm.count("depth"))
            goto help;

        int width = vm.at("width").as<int>();
        int depth = vm.at("depth").as<int>();

        if (width <= 0 || width % 4 != 0) {
            fprintf(stderr, "Hexfile width (%d bits) is not divisible by 4 or nonpositive!\n", width);
            return 1;
        }

        if (depth <= 0 || depth % 512 != 0) {
            fprintf(stderr, "Hexfile number of words (%d) is not divisible by 512 or nonpositive!\n", depth);
            return 1;
        }

        if (vm.count("seed")) {
            seed_nr = vm.at("seed").as<int>();

            if (verbose)
                fprintf(stderr, "Seed: %d\n", seed_nr);
        }

        x  =  uint64_t(seed_nr) << 32;
        x ^= uint64_t(seed_nr) << 20;
        x ^= uint64_t(seed_nr);

        x ^= uint64_t(depth) << 16;
        x ^= uint64_t(width) << 10;

        xorshift64star();
        xorshift64star();
        xorshift64star();

        if (!vm.count("seed")) {
#ifdef _WIN32
            SYSTEMTIME system_time;
            FILETIME file_time;
            uint64_t time;
            GetSystemTime(&system_time);
            SystemTimeToFileTime(&system_time, &file_time);
            x ^= uint64_t(file_time.dwLowDateTime);
            x ^= uint64_t(file_time.dwHighDateTime) << 32;
#else
            struct timeval tv;
            gettimeofday(&tv, NULL);
            x ^= uint64_t(tv.tv_sec) << 20;
            x ^= uint64_t(tv.tv_usec);
#endif
        }

        xorshift64star();
        xorshift64star();
        xorshift64star();

        ofstream romfile(vm.at("generate").as<std::string>());

        for (int i = 0; i < depth; i++) {
            for (int j = 0; j < width / 4; j++) {
                int digit = xorshift64star() & 15;
                romfile << "0123456789abcdef"[digit];
            }
            romfile << std::endl;
        }

        return 0;
    }

    if (!vm.count("input") || !vm.count("output") || !vm.count("from") || !vm.count("to"))
        goto help;

    // -------------------------------------------------------
    // Load from_hexfile and to_hexfile

    const char *from_hexfile_n = vm.at("from").as<std::string>().c_str();
    ifstream from_hexfile_f(from_hexfile_n);
    vector<vector<bool>> from_hexfile;

    const char *to_hexfile_n = vm.at("to").as<std::string>().c_str();
    ifstream to_hexfile_f(to_hexfile_n);
    vector<vector<bool>> to_hexfile;

    string line;

    for (int i = 1; getline(from_hexfile_f, line); i++)
        parse_hexfile_line(from_hexfile_n, i, from_hexfile, line);

    for (int i = 1; getline(to_hexfile_f, line); i++)
        parse_hexfile_line(to_hexfile_n, i, to_hexfile, line);

    if (to_hexfile.size() > 0 && from_hexfile.size() > to_hexfile.size()) {
        if (verbose)
            fprintf(stderr, "Padding to_hexfile from %d words to %d\n",
                int(to_hexfile.size()), int(from_hexfile.size()));
        do
            to_hexfile.push_back(vector<bool>(to_hexfile.at(0).size()));
        while (from_hexfile.size() > to_hexfile.size());
    }

    if (from_hexfile.size() != to_hexfile.size()) {
        fprintf(stderr, "Hexfiles have different number of words! (%d vs. %d)\n", int(from_hexfile.size()), int(to_hexfile.size()));
        return 1;
    }

    if (from_hexfile.size() % 512 != 0) {
        fprintf(stderr, "Hexfile number of words (%d) is not divisible by 512!\n", int(from_hexfile.size()));
        return 1;
    }

    for (size_t i = 1; i < from_hexfile.size(); i++)
        if (from_hexfile.at(i-1).size() != from_hexfile.at(i).size()) {
            fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i), from_hexfile_n);
            return 1;
        }

    for (size_t i = 1; i < to_hexfile.size(); i++) {
        while (to_hexfile.at(i-1).size() > to_hexfile.at(i).size())
            to_hexfile.at(i).push_back(false);
        if (to_hexfile.at(i-1).size() != to_hexfile.at(i).size()) {
            fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i+1), to_hexfile_n);
            return 1;
        }
    }

    if (from_hexfile.size() == 0 || from_hexfile.at(0).size() == 0) {
        fprintf(stderr, "Empty from/to hexfiles!\n");
        return 1;
    }

    if (verbose)
        fprintf(stderr, "Loaded pattern for %d bits wide and %d words deep memory.\n", int(from_hexfile.at(0).size()), int(from_hexfile.size()));


    // -------------------------------------------------------
    // Create bitslices from pattern data

    map<vector<bool>, pair<vector<bool>, int>> pattern;

    for (int i = 0; i < int(from_hexfile.at(0).size()); i++)
    {
        vector<bool> pattern_from, pattern_to;

        for (int j = 0; j < int(from_hexfile.size()); j++)
        {
            pattern_from.push_back(from_hexfile.at(j).at(i));
            pattern_to.push_back(to_hexfile.at(j).at(i));

            if (pattern_from.size() == 512) {
                if (pattern.count(pattern_from)) {
                    fprintf(stderr, "Conflicting from pattern for bit slice from_hexfile[%d:%d][%d]!\n", j, j-255, i);
                    return 1;
                }
                pattern[pattern_from] = std::make_pair(pattern_to, 0);
                pattern_from.clear(), pattern_to.clear();
            }
        }

        assert(pattern_from.empty());
        assert(pattern_to.empty());
    }

    if (verbose)
        fprintf(stderr, "Extracted %d bit slices from from/to hexfile data.\n", int(pattern.size()));


    // -------------------------------------------------------
    // Load database and config

    ifstream config_file(vm.at("input").as<string>());

    try {
        Trellis::load_database(database_folder);
    } catch (runtime_error &e) {
        cerr << "Failed to load Trellis database: " << e.what() << endl;
        return 1;
    }

    string textcfg((std::istreambuf_iterator<char>(config_file)), std::istreambuf_iterator<char>());

    Trellis::ChipConfig cc;
    try {
        cc = Trellis::ChipConfig::from_string(textcfg);
    } catch (runtime_error &e) {
        cerr << "Failed to process input config: " << e.what() << endl;
        return 1;
    }

    // -------------------------------------------------------
    // Replace bram data

    int max_replace_cnt = 0;

    for (auto &bram_it : cc.bram_data)
    {
        auto &bram_data = bram_it.second;

        const int W[] =  {  1,  2,  4,  9, 18, 36 };
        const int NW[] = {  8,  8,  8,  9,  9,  9 };
        const int B[]  = { 32, 32, 32, 36, 36, 36 };

        for (int i = 0; i < 6; i++)
        {
            for (int j = 0; j < B[i]; j++)
            {
                vector<bool> from_bitslice;

                for (int k = 0; k < 512; k++)
                {
                    int bn = (k * W[i]) + (j % W[i]) + ((j/W[i]) * 512 * W[i]);
                    int word  = bn / NW[i];
                    int bit   = bn % NW[i];

                    from_bitslice.push_back((bram_data.at(word) & (1 << bit)) != 0);
                }

                auto p = pattern.find(from_bitslice);
                if (p != pattern.end())
                {
                    auto &to_bitslice = p->second.first;

                    for (int k = 0; k < 512; k++)
                    {
                        int bn = (k * W[i]) + (j % W[i]) + ((j/W[i]) * 512 * W[i]);
                        int word  = bn / NW[i];
                        int bit   = bn % NW[i];

                        if (to_bitslice.at(k))
                            bram_data.at(word) |=  (1 << bit);
                        else
                            bram_data.at(word) &= ~(1 << bit);
                    }

                    max_replace_cnt = std::max(++p->second.second, max_replace_cnt);
                }
            }
        }
    }

    // -------------------------------------------------------
    // Save the new config

    ofstream new_config_file(vm.at("output").as<std::string>());
    new_config_file << cc.to_string();

    return 0;
}
