#pragma once

#include "fesa/core/status.hpp"
#include "fesa/math/sparse_matrix.hpp"
#include "fesa/math/vector.hpp"

namespace fesa {

class DofManager;

struct PartitionedStiffness {
    SparseMatrix kff;
    SparseMatrix kfc;
    SparseMatrix kcf;
    SparseMatrix kcc;
};

// Applies the DofManager's stable elimination order without owning equation
// numbering, load assembly, or a solver policy.
class EssentialConstraints {
public:
    static Result<PartitionedStiffness> partition(
        const SparseMatrix& full,
        const DofManager& dofs);
    static Vector gatherFree(const Vector& full, const DofManager& dofs);
    static Vector gatherConstrained(
        const Vector& full,
        const DofManager& dofs);
    static Vector reconstructFull(
        const Vector& freeValues,
        const Vector& constrainedValues,
        const DofManager& dofs);
};

} // namespace fesa
