/*
 * Copyright 2022 Rive
 */

#include "rive/artboard.hpp"
#include "rive/file.hpp"
#include "rive/animation/linear_animation_instance.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/animation/state_machine_input_instance.hpp"
#include "utils/no_op_factory.hpp"

class JSoner {
    std::vector<bool> m_IsArray;

    void tab() {
        for (int i = 0; i < m_IsArray.size(); ++i) {
            printf("\t");
        }
    }
    void add_c(const char key[], char c) {
        this->tab();
        if (key) {
            printf("\"%s\": %c\n", key, c);
        } else {
            printf("%c\n", c);
        }
    }

public:
    JSoner() {}
    ~JSoner() {
        while (!m_IsArray.empty()) {
            this->pop();
        }
    }

    void add(const char key[], const char value[]) {
        this->tab();
        printf("\"%s\": \"%s\"\n", key, value);
    }
    void pushArray(const char key[] = nullptr) {
        this->add_c(key, '[');
        m_IsArray.push_back(true);
    }
    void pushStruct(const char key[] = nullptr) {
        this->add_c(key, '{');
        m_IsArray.push_back(false);
    }
    void pop() {
        assert(!m_IsArray.empty());
        char c = m_IsArray.front() ? ']' : '}';
        m_IsArray.pop_back();

        this->tab();
        printf("%c\n", c);
    }

    void add(const char key[], int value) { this->add(key, std::to_string(value).c_str()); }
};

//////////////////////////////////////////////////

static void dump(JSoner& js, rive::LinearAnimationInstance* anim) {
    js.pushStruct();
    js.add("name", anim->name().c_str());
    js.add("duration", std::to_string(anim->durationSeconds()).c_str());
    js.add("loop", std::to_string(anim->loopValue()).c_str());
    js.pop();
}

static void dump(JSoner& js, rive::StateMachineInstance* smi) {
    js.pushStruct();
    js.add("name", smi->name().c_str());
    if (auto count = smi->inputCount()) {
        js.pushArray("inputs");
        for (auto i = 0; i < count; ++i) {
            auto inp = smi->input(i);
            js.add("name", inp->name().c_str());
        }
        js.pop();
    }
    js.pop();
}

static void dump(JSoner& js, rive::ArtboardInstance* abi) {
    js.pushStruct();
    js.add("name", abi->name().c_str());
    if (auto count = abi->animationCount()) {
        js.pushArray("animations");
        for (size_t i = 0; i < count; ++i) {
            dump(js, abi->animationAt(i).get());
        }
        js.pop();
    }
    if (auto count = abi->stateMachineCount()) {
        js.pushArray("machines");
        for (size_t i = 0; i < count; ++i) {
            dump(js, abi->stateMachineAt(i).get());
        }
        js.pop();
    }
    js.pop();
}

static void dump(JSoner& js, rive::File* file) {
    auto count = file->artboardCount();
    js.pushArray("artboards");
    for (size_t i = 0; i < count; ++i) {
        dump(js, file->artboardAt(i).get());
    }
    js.pop();
}

static std::unique_ptr<rive::File> open_file(const char name[]) {
    FILE* f = fopen(name, "rb");
    if (!f) {
        return nullptr;
    }

    fseek(f, 0, SEEK_END);
    auto length = ftell(f);
    fseek(f, 0, SEEK_SET);

    std::vector<uint8_t> bytes(length);

    if (fread(bytes.data(), 1, length, f) != length) {
        printf("Failed to read file into bytes array\n");
        return nullptr;
    }

    static rive::NoOpFactory gFactory;
    return rive::File::import(rive::toSpan(bytes), &gFactory);
}

static bool is_arg(const char arg[], const char target[], const char alt[] = nullptr) {
    return !strcmp(arg, target) || (arg && !strcmp(arg, alt));
}

int main(int argc, const char* argv[]) {
    const char* filename = nullptr;

    for (int i = 1; i < argc; ++i) {
        if (is_arg(argv[i], "--file", "-f")) {
            filename = argv[++i];
            continue;
        }
        printf("Unrecognized argument %s\n", argv[i]);
        return 1;
    }

    if (!filename) {
        printf("Need --file filename\n");
        return 1;
    }

    auto file = open_file(filename);
    if (!file) {
        printf("Can't open %s\n", filename);
        return 1;
    }

    JSoner js;
    js.pushStruct();
    dump(js, file.get());
    return 0;
}
