/*
 * 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(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;
}
