/*
 * Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * Ada specifications generated by this assembler depend on the RP.PIO package,
 * available in rp2040_hal.
 *
 * https://github.com/JeremyGrosser/rp2040_hal
 * https://github.com/JeremyGrosser/pico_bsp
 * https://github.com/JeremyGrosser/pico_examples
 */

#include <algorithm>
#include <iostream>
#include <sstream>
#include "output_format.h"
#include "pio_disassembler.h"
#include "version.h"

struct ada_output : public output_format {
    struct factory {
        factory() {
            output_format::add(new ada_output());
        }
    };

    ada_output() : output_format("ada") {}

    std::string get_description() override {
        return "Ada specification";
    }

    void output_symbols(FILE *out, const std::vector<compiled_source::symbol> &symbols) {
        int count = 0;
        for (const auto &s : symbols) {
            if (!s.is_label) {
                fprintf(out, "%s : constant := %d;\n", s.name.c_str(), s.value);
                count++;
            }
        }
        if (count) {
            fprintf(out, "\n");
            count = 0;
        }
        for (const auto &s : symbols) {
            if (s.is_label) {
                fprintf(out, "   Offset_%s : constant := %d;\n", s.name.c_str(), s.value);
                count++;
            }
        }
        if (count) {
            fprintf(out, "\n");
        }
    }

    void ada_case(std::string &identifier) {
        for(std::string::size_type i = 0; i < identifier.size(); ++i) {
            if ((i == 0) || (identifier[i - 1] == '_')) {
                identifier[i] = toupper(identifier[i]);
            }
        }
    }

    void header(FILE *out, const std::string msg, const int indent) {
        const std::string dashes = std::string(msg.length() + 6, '-');
        const std::string indent_str= std::string(indent, ' ');
        fprintf(out, "%s%s\n", indent_str.c_str(), dashes.c_str());
        fprintf(out, "%s-- %s --\n", indent_str.c_str(), msg.c_str());
        fprintf(out, "%s%s\n", indent_str.c_str(), dashes.c_str());
        fprintf(out, "\n");
    }

    int output(std::string destination, std::vector<std::string> output_options,
               const compiled_source &source) override {

        for (const auto &program : source.programs) {
            for(const auto &p : program.lang_opts) {
                if (p.first.size() >= name.size() && p.first.compare(0, name.size(), name) == 0) {
                    std::cerr << "warning: " << name << " does not support output options; " << p.first << " lang_opt ignored.\n";
                }
            }
        }

        std::string package_name;

        switch (output_options.size()) {
            case 0:
                std::cerr << "error: missing package name options for Ada format" << std::endl;
                return 1;
            case 1:
                package_name = output_options[0]; // Package name from command options
                break;
            default:
                std::cerr << "error: too many options for Ada format" << std::endl;
                return 1;
        }

        FILE *out = open_single_output(destination);
        if (!out) return 1;

        std::stringstream header_string;
        header_string << "This file is autogenerated by pioasm version " << PIOASM_VERSION_STRING << "; do not edit!";
        header(out, header_string.str(), 0);
        fprintf(out, "pragma Style_Checks (Off);\n\n");
        fprintf(out, "with RP.PIO;\n\n");

        fprintf(out, "package %s is\n", package_name.c_str());

        for (const auto &program : source.programs) {
            std::string trailing_comma = ", ";

            std::string prog_name= program.name;
            ada_case(prog_name);

            fprintf(out, "\n");
            header(out, prog_name, 3);


            output_symbols(out, source.global_symbols);
            fprintf(out, "   %s_Wrap_Target : constant := %d;\n", prog_name.c_str(), program.wrap_target);
            fprintf(out, "   %s_Wrap        : constant := %d;\n", prog_name.c_str(), program.wrap);
            fprintf(out, "\n");

            output_symbols(out, program.symbols);

            fprintf(out, "   %s_Program_Instructions : RP.PIO.Program := (\n", prog_name.c_str());
            for (int i = 0; i < (int)program.instructions.size(); i++) {
                const auto &inst = program.instructions[i];
                if (i == program.wrap_target) {
                    fprintf(out, "                    --  .wrap_target\n");
                }
                if (i == (int)program.instructions.size() - 1) {
                    trailing_comma = ");";
                }
                fprintf(out, "         16#%04x#%s --  %2d: %s\n", (uint16_t)inst, trailing_comma.c_str(), i,
                        disassemble(inst, program.sideset_bits_including_opt.get(), program.sideset_opt).c_str());
                if (i == program.wrap) {
                    fprintf(out, "                    --  .wrap\n");
                }
            }
        }
        fprintf(out, "\n");
        fprintf(out, "end %s;\n", package_name.c_str());
        fclose(out);
        return 0;
    }
};

static ada_output::factory creator;
