/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

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

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

    c_sdk_output() : output_format("c-sdk") {}

    std::string get_description() override {
        return "C header suitable for use with the Raspberry Pi Pico SDK";
    }

    void output_symbols(FILE *out, std::string prefix, const std::vector<compiled_source::symbol> &symbols) {
        int count = 0;
        for (const auto &s : symbols) {
            if (!s.is_label) {
                fprintf(out, "#define %s%s %d\n", prefix.c_str(), 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, "#define %soffset_%s %du\n", prefix.c_str(), s.name.c_str(), s.value);
                count++;
            }
        }
        if (count) {
            fprintf(out, "\n");
        }
    }

    void header(FILE *out, std::string msg) {
        std::string dashes = std::string(msg.length(), '-');
        fprintf(out, "// %s //\n", dashes.c_str());
        fprintf(out, "// %s //\n", msg.c_str());
        fprintf(out, "// %s //\n", 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";
                }
            }
        }
        FILE *out = open_single_output(destination);
        if (!out) return 1;

        header(out, "This file is autogenerated by pioasm; do not edit!");

        fprintf(out, "#if !PICO_NO_HARDWARE\n");
        fprintf(out, "#include \"hardware/pio.h\"\n");
        fprintf(out, "#endif\n");
        fprintf(out, "\n");

        output_symbols(out, "", source.global_symbols);

        for (const auto &program : source.programs) {
            header(out, program.name);

            std::string prefix = program.name + "_";

            fprintf(out, "#define %swrap_target %d\n", prefix.c_str(), program.wrap_target);
            fprintf(out, "#define %swrap %d\n", prefix.c_str(), program.wrap);
            fprintf(out, "\n");

            output_symbols(out, prefix, program.symbols);

            fprintf(out, "static const uint16_t %sprogram_instructions[] = {\n", prefix.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");
                }
                fprintf(out, "    0x%04x, // %2d: %s\n", inst, 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, "\n");

            fprintf(out, "#if !PICO_NO_HARDWARE\n");
            fprintf(out, "static const struct pio_program %sprogram = {\n", prefix.c_str());
            fprintf(out, "    .instructions = %sprogram_instructions,\n", prefix.c_str());
            fprintf(out, "    .length = %d,\n", (int) program.instructions.size());
            fprintf(out, "    .origin = %d,\n", program.origin.get());
            fprintf(out, "};\n");
            fprintf(out, "\n");
            fprintf(out, "static inline pio_sm_config %sprogram_get_default_config(uint offset) {\n", prefix.c_str());
            fprintf(out, "    pio_sm_config c = pio_get_default_sm_config();\n");
            fprintf(out, "    sm_config_set_wrap(&c, offset + %swrap_target, offset + %swrap);\n", prefix.c_str(),
                    prefix.c_str());
            if (program.sideset_bits_including_opt.is_specified()) {
                fprintf(out, "    sm_config_set_sideset(&c, %d, %s, %s);\n", program.sideset_bits_including_opt.get(),
                        program.sideset_opt ? "true" : "false",
                        program.sideset_pindirs ? "true" : "false");
            }
            fprintf(out, "    return c;\n");
            fprintf(out, "}\n");

            // todo maybe have some code blocks inside or outside here?
            for(const auto& o : program.code_blocks) {
                fprintf(out, "\n");
                if (o.first == name) {
                    for(const auto &contents : o.second) {
                        fprintf(out, "%s", contents.c_str());
                        fprintf(out, "\n");
                    }
                }
            }

            fprintf(out, "#endif\n");
            fprintf(out, "\n");
        }
        if (out != stdout) { fclose(out); }
        return 0;
    }
};

static c_sdk_output::factory creator;
