#pragma once

#include <optional>
#include <vector>

#include <fesa/core/diagnostic.hpp>
#include <fesa/model/domain.hpp>

namespace fesa {

struct DomainBuildResult final {
    std::optional<Domain> domain;
    std::vector<Diagnostic> diagnostics;
};

class DomainBuilder final {
public:
    void add_node(Node value);
    void add_material(IsotropicElastic value);
    void add_section(BeamSection value);
    void add_beam_element(BeamElement value);
    void add_node_set(NodeSet value);
    void add_element_set(ElementSet value);
    void set_step(StepDefinition value);
    [[nodiscard]] DomainBuildResult build() &&;

private:
    std::vector<Node> nodes_;
    std::vector<BeamElement> beam_elements_;
    std::vector<IsotropicElastic> materials_;
    std::vector<BeamSection> sections_;
    std::vector<NodeSet> node_sets_;
    std::vector<ElementSet> element_sets_;
    std::optional<StepDefinition> step_;
};

}  // namespace fesa
