/*
 * Copyright 2020-2022 F4PGA Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 */

#include "UhdmAst.h"
#include "frontends/ast/ast.h"
#include "kernel/yosys.h"
#include "uhdmcommonfrontend.h"

#if defined(_MSC_VER)
#include <direct.h>
#include <process.h>
#else
#include <sys/param.h>
#include <unistd.h>
#endif
#include <memory>

#include <list>

#include "Surelog/ErrorReporting/Report.h"
#include "Surelog/surelog.h"

namespace UHDM
{
extern void visit_object(vpiHandle obj_h, int indent, const char *relation, std::set<const BaseClass *> *visited, std::ostream &out,
                         bool shallowVisit = false);
}

namespace systemverilog_plugin
{

using namespace ::Yosys;

// Store systemverilog defaults to be passed for every invocation of read_systemverilog
static std::vector<std::string> systemverilog_defaults;
static std::list<std::vector<std::string>> systemverilog_defaults_stack;

// Store global definitions for top-level defines
static std::vector<std::string> systemverilog_defines;

// SURELOG::scompiler wrapper.
// Owns UHDM/VPI resources used by designs returned from `execute`
class Compiler
{
  public:
    Compiler() = default;
    ~Compiler()
    {
        if (this->scompiler) {
            SURELOG::shutdown_compiler(this->scompiler);
        }
    }

    const std::vector<vpiHandle> &execute(std::unique_ptr<SURELOG::ErrorContainer> errors, std::unique_ptr<SURELOG::CommandLineParser> clp)
    {
        log_assert(!this->errors && !this->clp && !this->scompiler);

        bool success = true;
        bool noFatalErrors = true;
        unsigned int codedReturn = 0;
        clp->setWriteUhdm(false);
        errors->printMessages(clp->muteStdout());
        if (success && (!clp->help())) {
            this->scompiler = SURELOG::start_compiler(clp.get());
            if (!this->scompiler)
                codedReturn |= 1;
            this->designs.push_back(SURELOG::get_uhdm_design(this->scompiler));
        }
        SURELOG::ErrorContainer::Stats stats;
        if (!clp->help()) {
            stats = errors->getErrorStats();
            if (stats.nbFatal)
                codedReturn |= 1;
            if (stats.nbSyntax)
                codedReturn |= 2;
        }
        bool noFErrors = true;
        if (!clp->help())
            noFErrors = errors->printStats(stats, clp->muteStdout());
        if (noFErrors == false) {
            noFatalErrors = false;
        }
        if ((!noFatalErrors) || (!success) || (errors->getErrorStats().nbError))
            codedReturn |= 1;
        if (codedReturn) {
            log_error("Error when parsing design. Aborting!\n");
        }

        this->clp = std::move(clp);
        this->errors = std::move(errors);

        return this->designs;
    }

  private:
    std::unique_ptr<SURELOG::ErrorContainer> errors = nullptr;
    std::unique_ptr<SURELOG::CommandLineParser> clp = nullptr;
    SURELOG::scompiler *scompiler = nullptr;
    std::vector<vpiHandle> designs = {};
};

struct UhdmSurelogAstFrontend : public UhdmCommonFrontend {
    UhdmSurelogAstFrontend(std::string name, std::string short_help) : UhdmCommonFrontend(name, short_help) {}
    UhdmSurelogAstFrontend() : UhdmCommonFrontend("verilog_with_uhdm", "generate/read UHDM file") {}
    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("    read_verilog_with_uhdm [options] [filenames]\n");
        log("\n");
        log("Read SystemVerilog files using Surelog into the current design\n");
        log("\n");
        this->print_read_options();
    }
    AST::AstNode *parse(std::string filename) override
    {
        std::vector<const char *> cstrings;
        bool link = false;
        if (this->shared.formal) {
            systemverilog_defines.push_back("-DFORMAL=1");
        } else {
            systemverilog_defines.push_back("-DSYNTHESIS=1");
        }
        cstrings.reserve(this->args.size() + systemverilog_defaults.size() + systemverilog_defines.size());
        for (size_t i = 0; i < this->args.size(); ++i) {
            cstrings.push_back(const_cast<char *>(this->args[i].c_str()));
            if (this->args[i] == "-link")
                link = true;
        }

        if (!link) {
            // Add systemverilog defaults args
            for (size_t i = 0; i < systemverilog_defaults.size(); ++i) {
                // Convert args to surelog compatible
                if (systemverilog_defaults[i] == "-defer")
                    this->shared.defer = true;
                // Pass any remainings args directly to surelog
                else
                    cstrings.push_back(const_cast<char *>(systemverilog_defaults[i].c_str()));
            }

            // Add systemverilog defines args
            for (size_t i = 0; i < systemverilog_defines.size(); ++i)
                cstrings.push_back(const_cast<char *>(systemverilog_defines[i].c_str()));
        }

        auto symbolTable = std::make_unique<SURELOG::SymbolTable>();
        auto errors = std::make_unique<SURELOG::ErrorContainer>(symbolTable.get());
        auto clp = std::make_unique<SURELOG::CommandLineParser>(errors.get(), symbolTable.get(), false, false);
        bool success = clp->parseCommandLine(cstrings.size(), &cstrings[0]);
        if (!success) {
            log_error("Error parsing Surelog arguments!\n");
        }
        // Force -parse flag settings even if it wasn't specified
        clp->setwritePpOutput(true);
        clp->setParse(true);
        clp->fullSVMode(true);
        clp->setCacheAllowed(true);
        if (this->shared.defer) {
            clp->setCompile(false);
            clp->setElaborate(false);
            clp->setSepComp(true);
        } else {
            clp->setCompile(true);
            clp->setElaborate(true);
        }
        if (this->shared.link) {
            clp->setLink(true);
        }

        Compiler compiler;
        const auto &uhdm_designs = compiler.execute(std::move(errors), std::move(clp));

        if (this->shared.debug_flag || !this->report_directory.empty()) {
            for (auto design : uhdm_designs) {
                std::ofstream null_stream;
                UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : null_stream);
            }
        }

        // on parse_only mode, don't try to load design
        // into yosys
        if (this->shared.parse_only)
            return nullptr;

        if (this->shared.defer && !this->shared.link)
            return nullptr;

        // FIXME: SynthSubset annotation is incompatible with separate compilation
        // `-defer` turns elaboration off, so check for it
        // Should be called 1. for normal flow 2. after finishing with `-link`
        if (!this->shared.defer) {
            UHDM::Serializer serializer;
            UHDM::SynthSubset *synthSubset =
              make_new_object_with_optional_extra_true_arg<UHDM::SynthSubset>(&serializer, this->shared.nonSynthesizableObjects, false);
            synthSubset->listenDesigns(uhdm_designs);
            delete synthSubset;
        }

        UhdmAst uhdm_ast(this->shared);
        AST::AstNode *current_ast = uhdm_ast.visit_designs(uhdm_designs);
        if (!this->report_directory.empty()) {
            this->shared.report.write(this->report_directory);
        }

        // FIXME: Check and reset remaining shared data
        this->shared.top_nodes.clear();
        this->shared.nonSynthesizableObjects.clear();
        return current_ast;
    }
    void call_log_header(RTLIL::Design *design) override { log_header(design, "Executing Verilog with UHDM frontend.\n"); }
} UhdmSurelogAstFrontend;

struct UhdmSystemVerilogFrontend : public UhdmSurelogAstFrontend {
    UhdmSystemVerilogFrontend() : UhdmSurelogAstFrontend("systemverilog", "read SystemVerilog files") {}
    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("    read_systemverilog [options] [filenames]\n");
        log("\n");
        log("Read SystemVerilog files using Surelog into the current design\n");
        log("\n");
        this->print_read_options();
        log("    -Ipath\n");
        log("        add include path.\n");
        log("\n");
        log("    -Pparameter=value\n");
        log("        define parameter as value.\n");
        log("\n");
    }
} UhdmSystemVerilogFrontend;

struct SystemVerilogDefaults : public Pass {
    SystemVerilogDefaults() : Pass("systemverilog_defaults", "set default options for read_systemverilog") {}
    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("    systemverilog_defaults -add [options]\n");
        log("\n");
        log("Add the specified options to the list of default options to read_systemverilog.\n");
        log("\n");
        log("\n");
        log("    systemverilog_defaults -clear\n");
        log("\n");
        log("Clear the list of Systemverilog default options.\n");
        log("\n");
        log("\n");
        log("    systemverilog_defaults -push\n");
        log("    systemverilog_defaults -pop\n");
        log("\n");
        log("Push or pop the list of default options to a stack. Note that -push does\n");
        log("not imply -clear.\n");
        log("\n");
    }
    void execute(std::vector<std::string> args, RTLIL::Design *) override
    {
        if (args.size() < 2)
            cmd_error(args, 1, "Missing argument.");

        if (args[1] == "-add") {
            systemverilog_defaults.insert(systemverilog_defaults.end(), args.begin() + 2, args.end());
            return;
        }

        if (args.size() != 2)
            cmd_error(args, 2, "Extra argument.");

        if (args[1] == "-clear") {
            systemverilog_defaults.clear();
            return;
        }

        if (args[1] == "-push") {
            systemverilog_defaults_stack.push_back(systemverilog_defaults);
            return;
        }

        if (args[1] == "-pop") {
            if (systemverilog_defaults_stack.empty()) {
                systemverilog_defaults.clear();
            } else {
                systemverilog_defaults.swap(systemverilog_defaults_stack.back());
                systemverilog_defaults_stack.pop_back();
            }
            return;
        }
    }
} SystemVerilogDefaults;

struct SystemVerilogDefines : public Pass {
    SystemVerilogDefines() : Pass("systemverilog_defines", "define and undefine systemverilog defines")
    {
        systemverilog_defines.push_back("-DYOSYS=1");
    }
    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("    systemverilog_defines [options]\n");
        log("\n");
        log("Define and undefine systemverilog preprocessor macros.\n");
        log("\n");
        log("    -Dname[=definition]\n");
        log("        define the preprocessor symbol 'name' and set its optional value\n");
        log("        'definition'\n");
        log("\n");
        log("    -Uname[=definition]\n");
        log("        undefine the preprocessor symbol 'name'\n");
        log("\n");
        log("    -reset\n");
        log("        clear list of defined preprocessor symbols\n");
        log("\n");
        log("    -list\n");
        log("        list currently defined preprocessor symbols\n");
        log("\n");
    }
    void remove(const std::string name)
    {
        auto it = systemverilog_defines.begin();
        while (it != systemverilog_defines.end()) {
            std::string nm;
            size_t equal = (*it).find('=', 2);
            if (equal == std::string::npos)
                nm = (*it).substr(2, std::string::npos);
            else
                nm = (*it).substr(2, equal - 2);
            if (name == nm)
                systemverilog_defines.erase(it);
            else
                it++;
        }
    }
    void dump(void)
    {
        for (size_t i = 0; i < systemverilog_defines.size(); ++i) {
            std::string name, value = "";
            size_t equal = systemverilog_defines[i].find('=', 2);
            name = systemverilog_defines[i].substr(2, equal - 2);
            if (equal != std::string::npos)
                value = systemverilog_defines[i].substr(equal + 1, std::string::npos);
            Yosys::log("`define %s %s\n", name.c_str(), value.c_str());
        }
    }
    void execute(std::vector<std::string> args, RTLIL::Design *design) override
    {
        size_t argidx;
        for (argidx = 1; argidx < args.size(); argidx++) {
            std::string arg = args[argidx];
            if (arg == "-D" && argidx + 1 < args.size()) {
                systemverilog_defines.push_back("-D" + args[++argidx]);
                continue;
            }
            if (arg.compare(0, 2, "-D") == 0) {
                systemverilog_defines.push_back(arg);
                continue;
            }
            if (arg == "-U" && argidx + 1 < args.size()) {
                std::string name = args[++argidx];
                this->remove(name);
                continue;
            }
            if (arg.compare(0, 2, "-U") == 0) {
                std::string name = arg.substr(2);
                this->remove(name);
                continue;
            }
            if (arg == "-reset") {
                systemverilog_defines.erase(systemverilog_defines.begin() + 1, systemverilog_defines.end());
                continue;
            }
            if (arg == "-list") {
                this->dump();
                continue;
            }
            break;
        }

        if (args.size() != argidx)
            cmd_error(args, argidx, "Extra argument.");
    }
} SystemVerilogDefines;

} // namespace systemverilog_plugin
