/*
 * 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 "output_format.h"
#include "pio_disassembler.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;

        header(out, "This file is autogenerated by pioasm; do not edit!", 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", 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;
