#pragma once

#include "fesa/core/status.hpp"
#include "fesa/model/model_types.hpp"

#include <filesystem>
#include <string>
#include <vector>

namespace fesa {

// Owns the complete semantic definition. Public access remains const so a
// vector position can serve as a stable internal index after construction.
class Domain {
public:
    static Result<Domain> create(ModelDefinition definition);

    const std::vector<Node>& nodes() const noexcept;
    const std::vector<EulerBeam3DDefinition>& elements() const noexcept;
    const std::vector<Mitc4ShellDefinition>& shellElements() const noexcept;
    const std::vector<LinearElasticMaterial>& materials() const noexcept;
    const std::vector<GeneralBeamSection>& sections() const noexcept;
    const std::vector<ShellSection>& shellSections() const noexcept;
    const std::vector<ShellNodeInitialFrame>& shellNodeInitialFrames() const noexcept;
    const std::vector<NodeSet>& nodeSets() const noexcept;
    const std::vector<ElementSet>& elementSets() const noexcept;
    const std::vector<StaticStepDefinition>& steps() const noexcept;
    const std::vector<Diagnostic>& warnings() const noexcept;
    const std::filesystem::path& sourcePath() const noexcept;
    const std::string& sourceContentIdentity() const noexcept;

private:
    explicit Domain(ModelDefinition definition);

    ModelDefinition definition_;
};

} // namespace fesa
