#pragma once

#include <optional>
#include <span>
#include <vector>

#include <fesa/assembly/equation_system.hpp>
#include <fesa/core/diagnostic.hpp>
#include <fesa/fem/dof_manager.hpp>

namespace fesa {

struct ReducedSystem final {
    SymmetricCsr stiffness;
    std::vector<double> force;
};

struct ConstraintResult final {
    std::optional<ReducedSystem> reduced_system;
    std::vector<Diagnostic> diagnostics;
};

[[nodiscard]] ConstraintResult eliminate_essential_bcs(
    const EquationSystem& original,
    const DofManager& dofs);

[[nodiscard]] std::vector<double> recover_reaction(
    const EquationSystem& original,
    std::span<const double> full_displacement);

}  // namespace fesa
