/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com>
 *  Copyright (C) 2018  Miodrag Milanovic <miodrag@symbioticeda.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.
 *
 */

#ifndef NO_GUI
#include <QApplication>
#include "application.h"
#include "mainwindow.h"
#endif
#ifndef NO_PYTHON
#include "pybindings.h"
#endif

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/program_options.hpp>
#include <fstream>
#include <iostream>
#include "command.h"
#include "design_utils.h"
#include "json_frontend.h"
#include "jsonparse.h"
#include "jsonwrite.h"
#include "log.h"
#include "timing.h"
#include "util.h"
#include "version.h"

NEXTPNR_NAMESPACE_BEGIN

CommandHandler::CommandHandler(int argc, char **argv) : argc(argc), argv(argv) { log_streams.clear(); }

bool CommandHandler::parseOptions()
{
    options.add(getGeneralOptions()).add(getArchOptions());
    try {
        po::parsed_options parsed =
                po::command_line_parser(argc, argv)
                        .style(po::command_line_style::default_style ^ po::command_line_style::allow_guessing)
                        .options(options)
                        .positional(pos)
                        .run();
        po::store(parsed, vm);
        po::notify(vm);
        return true;
    } catch (std::exception &e) {
        std::cout << e.what() << "\n";
        return false;
    }
}

bool CommandHandler::executeBeforeContext()
{
    if (vm.count("help") || argc == 1) {
        std::cerr << boost::filesystem::basename(argv[0])
                  << " -- Next Generation Place and Route (git sha1 " GIT_COMMIT_HASH_STR ")\n";
        std::cerr << options << "\n";
        return argc != 1;
    }

    if (vm.count("version")) {
        std::cerr << boost::filesystem::basename(argv[0])
                  << " -- Next Generation Place and Route (git sha1 " GIT_COMMIT_HASH_STR ")\n";
        return true;
    }
    validate();

    if (vm.count("quiet")) {
        log_streams.push_back(std::make_pair(&std::cerr, LogLevel::WARNING_MSG));
    } else {
        log_streams.push_back(std::make_pair(&std::cerr, LogLevel::LOG_MSG));
    }

    if (vm.count("log")) {
        std::string logfilename = vm["log"].as<std::string>();
        logfile.open(logfilename);
        if (!logfile.is_open())
            log_error("Failed to open log file '%s' for writing.\n", logfilename.c_str());
        log_streams.push_back(std::make_pair(&logfile, LogLevel::LOG_MSG));
    }
    return false;
}

po::options_description CommandHandler::getGeneralOptions()
{
    po::options_description general("General options");
    general.add_options()("help,h", "show help");
    general.add_options()("verbose,v", "verbose output");
    general.add_options()("quiet,q", "quiet mode, only errors and warnings displayed");
    general.add_options()("log,l", po::value<std::string>(),
                          "log file, all log messages are written to this file regardless of -q");
    general.add_options()("debug", "debug output");
    general.add_options()("force,f", "keep running after errors");
#ifndef NO_GUI
    general.add_options()("gui", "start gui");
    general.add_options()("gui-no-aa", "disable anti aliasing (use together with --gui option)");
#endif
#ifndef NO_PYTHON
    general.add_options()("run", po::value<std::vector<std::string>>(),
                          "python file to execute instead of default flow");
    pos.add("run", -1);
    general.add_options()("pre-pack", po::value<std::vector<std::string>>(), "python file to run before packing");
    general.add_options()("pre-place", po::value<std::vector<std::string>>(), "python file to run before placement");
    general.add_options()("pre-route", po::value<std::vector<std::string>>(), "python file to run before routing");
    general.add_options()("post-route", po::value<std::vector<std::string>>(), "python file to run after routing");

#endif
    general.add_options()("json", po::value<std::string>(), "JSON design file to ingest");
    general.add_options()("write", po::value<std::string>(), "JSON design file to write");
    general.add_options()("seed", po::value<int>(), "seed value for random number generator");
    general.add_options()("randomize-seed,r", "randomize seed value for random number generator");

    general.add_options()(
            "placer", po::value<std::string>(),
            std::string("placer algorithm to use; available: " + boost::algorithm::join(Arch::availablePlacers, ", ") +
                        "; default: " + Arch::defaultPlacer)
                    .c_str());

    general.add_options()("slack_redist_iter", po::value<int>(), "number of iterations between slack redistribution");
    general.add_options()("cstrweight", po::value<float>(), "placer weighting for relative constraint satisfaction");
    general.add_options()("starttemp", po::value<float>(), "placer SA start temperature");
    general.add_options()("placer-budgets", "use budget rather than criticality in placer timing weights");

    general.add_options()("pack-only", "pack design only without placement or routing");
    general.add_options()("no-route", "process design without routing");
    general.add_options()("no-place", "process design without placement");
    general.add_options()("no-pack", "process design without packing");

    general.add_options()("ignore-loops", "ignore combinational loops in timing analysis");

    general.add_options()("version,V", "show version");
    general.add_options()("test", "check architecture database integrity");
    general.add_options()("freq", po::value<double>(), "set target frequency for design in MHz");
    general.add_options()("timing-allow-fail", "allow timing to fail in design");
    general.add_options()("no-tmdriv", "disable timing-driven placement");
    general.add_options()("sdf", po::value<std::string>(), "SDF delay back-annotation file to write");
    general.add_options()("sdf-cvc", "enable tweaks for SDF file compatibility with the CVC simulator");

    return general;
}

void CommandHandler::setupContext(Context *ctx)
{
    if (ctx->settings.find(ctx->id("seed")) != ctx->settings.end())
        ctx->rngstate = ctx->setting<uint64_t>("seed");

    if (vm.count("verbose")) {
        ctx->verbose = true;
    }

    if (vm.count("debug")) {
        ctx->verbose = true;
        ctx->debug = true;
    }

    if (vm.count("force")) {
        ctx->force = true;
    }

    if (vm.count("seed")) {
        ctx->rngseed(vm["seed"].as<int>());
    }

    if (vm.count("randomize-seed")) {
        srand(time(NULL));
        int r;
        do {
            r = rand();
        } while (r == 0);
        ctx->rngseed(r);
    }

    if (vm.count("slack_redist_iter")) {
        ctx->settings[ctx->id("slack_redist_iter")] = vm["slack_redist_iter"].as<int>();
        if (vm.count("freq") && vm["freq"].as<double>() == 0) {
            ctx->settings[ctx->id("auto_freq")] = true;
#ifndef NO_GUI
            if (!vm.count("gui"))
#endif
                log_warning("Target frequency not specified. Will optimise for max frequency.\n");
        }
    }

    if (vm.count("ignore-loops")) {
        ctx->settings[ctx->id("timing/ignoreLoops")] = true;
    }

    if (vm.count("timing-allow-fail")) {
        ctx->settings[ctx->id("timing/allowFail")] = true;
    }

    if (vm.count("placer")) {
        std::string placer = vm["placer"].as<std::string>();
        if (std::find(Arch::availablePlacers.begin(), Arch::availablePlacers.end(), placer) ==
            Arch::availablePlacers.end())
            log_error("Placer algorithm '%s' is not supported (available options: %s)\n", placer.c_str(),
                      boost::algorithm::join(Arch::availablePlacers, ", ").c_str());
        ctx->settings[ctx->id("placer")] = placer;
    }

    if (vm.count("cstrweight")) {
        ctx->settings[ctx->id("placer1/constraintWeight")] = std::to_string(vm["cstrweight"].as<float>());
    }
    if (vm.count("starttemp")) {
        ctx->settings[ctx->id("placer1/startTemp")] = std::to_string(vm["starttemp"].as<float>());
    }

    if (vm.count("placer-budgets")) {
        ctx->settings[ctx->id("placer1/budgetBased")] = true;
    }
    if (vm.count("freq")) {
        auto freq = vm["freq"].as<double>();
        if (freq > 0)
            ctx->settings[ctx->id("target_freq")] = std::to_string(freq * 1e6);
    }

    if (vm.count("no-tmdriv"))
        ctx->settings[ctx->id("timing_driven")] = false;

    // Setting default values
    if (ctx->settings.find(ctx->id("target_freq")) == ctx->settings.end())
        ctx->settings[ctx->id("target_freq")] = std::to_string(12e6);
    if (ctx->settings.find(ctx->id("timing_driven")) == ctx->settings.end())
        ctx->settings[ctx->id("timing_driven")] = true;
    if (ctx->settings.find(ctx->id("slack_redist_iter")) == ctx->settings.end())
        ctx->settings[ctx->id("slack_redist_iter")] = 0;
    if (ctx->settings.find(ctx->id("auto_freq")) == ctx->settings.end())
        ctx->settings[ctx->id("auto_freq")] = false;
    if (ctx->settings.find(ctx->id("placer")) == ctx->settings.end())
        ctx->settings[ctx->id("placer")] = Arch::defaultPlacer;

    ctx->settings[ctx->id("arch.name")] = std::string(ctx->archId().c_str(ctx));
    ctx->settings[ctx->id("arch.type")] = std::string(ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
    ctx->settings[ctx->id("seed")] = ctx->rngstate;
}

int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
{
    if (vm.count("test")) {
        ctx->archcheck();
        return 0;
    }

#ifndef NO_GUI
    if (vm.count("gui")) {
        Application a(argc, argv, (vm.count("gui-no-aa") > 0));
        MainWindow w(std::move(ctx), this);
        try {
            if (vm.count("json")) {
                std::string filename = vm["json"].as<std::string>();
                std::ifstream f(filename);
#ifdef LEGACY_FRONTEND
                if (!parse_json_file(f, filename, w.getContext()))
                    log_error("Loading design failed.\n");
#else
                if (!parse_json(f, filename, w.getContext()))
                    log_error("Loading design failed.\n");
#endif
                customAfterLoad(w.getContext());
                w.notifyChangeContext();
                w.updateActions();
            } else
                w.notifyChangeContext();
        } catch (log_execution_error_exception) {
            // show error is handled by gui itself
        }
        w.show();

        return a.exec();
    }
#endif
    if (vm.count("json")) {
        std::string filename = vm["json"].as<std::string>();
        std::ifstream f(filename);
#ifdef LEGACY_FRONTEND
        if (!parse_json_file(f, filename, ctx.get()))
            log_error("Loading design failed.\n");
#else
        if (!parse_json(f, filename, ctx.get()))
            log_error("Loading design failed.\n");
#endif

        customAfterLoad(ctx.get());
    }

#ifndef NO_PYTHON
    init_python(argv[0], true);
    python_export_global("ctx", *ctx);

    if (vm.count("run")) {

        std::vector<std::string> files = vm["run"].as<std::vector<std::string>>();
        for (auto filename : files)
            execute_python_file(filename.c_str());
    } else
#endif
            if (vm.count("json")) {
        bool do_pack = vm.count("pack-only") != 0 || vm.count("no-pack") == 0;
        bool do_place = vm.count("pack-only") == 0 && vm.count("no-place") == 0;
        bool do_route = vm.count("pack-only") == 0 && vm.count("no-route") == 0;

        if (do_pack) {
            run_script_hook("pre-pack");
            if (!ctx->pack() && !ctx->force)
                log_error("Packing design failed.\n");
        }
        assign_budget(ctx.get());
        ctx->check();
        print_utilisation(ctx.get());

        if (do_place) {
            run_script_hook("pre-place");
            if (!ctx->place() && !ctx->force)
                log_error("Placing design failed.\n");
            ctx->check();
        }

        if (do_route) {
            run_script_hook("pre-route");
            if (!ctx->route() && !ctx->force)
                log_error("Routing design failed.\n");
            run_script_hook("post-route");
        }

        customBitstream(ctx.get());
    }

    if (vm.count("write")) {
        std::string filename = vm["write"].as<std::string>();
        std::ofstream f(filename);
        if (!write_json_file(f, filename, ctx.get()))
            log_error("Saving design failed.\n");
    }

    if (vm.count("sdf")) {
        std::string filename = vm["sdf"].as<std::string>();
        std::ofstream f(filename);
        if (!f)
            log_error("Failed to open SDF file '%s' for writing.\n", filename.c_str());
        ctx->writeSDF(f, vm.count("sdf-cvc"));
    }

#ifndef NO_PYTHON
    deinit_python();
#endif

    return had_nonfatal_error ? 1 : 0;
}

void CommandHandler::conflicting_options(const boost::program_options::variables_map &vm, const char *opt1,
                                         const char *opt2)
{
    if (vm.count(opt1) && !vm[opt1].defaulted() && vm.count(opt2) && !vm[opt2].defaulted()) {
        std::string msg = "Conflicting options '" + std::string(opt1) + "' and '" + std::string(opt2) + "'.";
        log_error("%s\n", msg.c_str());
    }
}

void CommandHandler::printFooter()
{
    int warning_count = get_or_default(message_count_by_level, LogLevel::WARNING_MSG, 0),
        error_count = get_or_default(message_count_by_level, LogLevel::ERROR_MSG, 0);
    if (warning_count > 0 || error_count > 0)
        log_always("%d warning%s, %d error%s\n", warning_count, warning_count == 1 ? "" : "s", error_count,
                   error_count == 1 ? "" : "s");
}

int CommandHandler::exec()
{
    try {
        if (!parseOptions())
            return -1;

        if (executeBeforeContext())
            return 0;

        std::unordered_map<std::string, Property> values;
        if (vm.count("json")) {
            std::string filename = vm["json"].as<std::string>();
            std::ifstream f(filename);
            if (!load_json_settings(f, filename, values))
                log_error("Loading design failed.\n");
        }
        std::unique_ptr<Context> ctx = createContext(values);
        setupContext(ctx.get());
        setupArchContext(ctx.get());
        int rc = executeMain(std::move(ctx));
        printFooter();
        return rc;
    } catch (log_execution_error_exception) {
        printFooter();
        return -1;
    }
}

std::unique_ptr<Context> CommandHandler::load_json(std::string filename)
{
    vm.clear();
    std::unordered_map<std::string, Property> values;
    {
        std::ifstream f(filename);
        if (!load_json_settings(f, filename, values))
            log_error("Loading design failed.\n");
    }
    std::unique_ptr<Context> ctx = createContext(values);
    setupContext(ctx.get());
    setupArchContext(ctx.get());
    {
        std::ifstream f(filename);
        if (!parse_json_file(f, filename, ctx.get()))
            log_error("Loading design failed.\n");
    }
    customAfterLoad(ctx.get());
    return ctx;
}

void CommandHandler::run_script_hook(const std::string &name)
{
#ifndef NO_PYTHON
    if (vm.count(name)) {
        std::vector<std::string> files = vm[name].as<std::vector<std::string>>();
        for (auto filename : files)
            execute_python_file(filename.c_str());
    }
#endif
}

NEXTPNR_NAMESPACE_END
