#pragma once

#include "errors/errors.hpp"
#include "resources/material.hpp"
#include "resources/mesh.hpp"

#include <fastgltf/core.hpp>

#include <expected>
#include <filesystem>
#include <vector>

namespace kuiper::resource
{

class model {
  public:
    using mesh_storage     = std::vector<mesh>;
    using material_storage = std::vector<material>;

    model() = default;
    model(std::initializer_list<mesh> meshes) {
        for (const auto& m : meshes) {
            m_meshes.push_back(m);
        }
    }

    void push_mesh(const mesh& m) {
        return m_meshes.push_back(m);
    }

    void push_material(const material& m) {
        return m_materials.push_back(m);
    }

    const mesh_storage& meshes() const noexcept {
        return m_meshes;
    }

    const material_storage& materials() const noexcept {
        return m_materials;
    }

    /// Construct a `model` from a path to a glTF file
    static std::expected<model, kuiper::error> from_gltf_path(const std::filesystem::path& gltf_path);
    /// Construct a `model` from a path to a glTF file, prefer this function to the above as fastgltf's `Parser` should
    /// ideally be re-used (only on one thread, though)
    static std::expected<model, kuiper::error> from_gltf_path(const std::filesystem::path& gltf_path,
                                                              fastgltf::Parser&            gltf_parser);

  private:
    mesh_storage     m_meshes;
    material_storage m_materials;
};

} // namespace kuiper::resource
