#pragma once

#include <utility>

namespace renderive::detail {

struct Artifact_Transaction_Result {
    bool artifact_emitted{};
    bool stream_available{};
    bool target_attached{};
    bool stream_executed{};
    bool execution_succeeded{};

    [[nodiscard]] explicit operator bool() const noexcept {
        return artifact_emitted && stream_available && target_attached &&
               stream_executed && execution_succeeded;
    }
};

template <class Api>
[[nodiscard]] Artifact_Transaction_Result execute_ordered_artifact_transaction(Api& api) {
    Artifact_Transaction_Result result;
    auto* artifact = api.emit();
    if (artifact == nullptr)
        return result;
    result.artifact_emitted = true;

    struct Artifact_Guard {
        Api& api;
        decltype(artifact) artifact;
        ~Artifact_Guard() { api.destroy(*artifact); }
    } guard{api, artifact};

    auto* stream = api.stream(*artifact);
    if (stream == nullptr)
        return result;
    result.stream_available = true;

    result.target_attached = api.attach();
    result.stream_executed = true;
    result.execution_succeeded = api.execute(*stream);
    return result;
}

} // namespace renderive::detail
