use axum::{body::Bytes, extract::Path, extract::State, http::StatusCode, response::IntoResponse};
use std::sync::Arc;
use velesdb_core::wire::vrb1;
use super::upsert_result_to_response;
use crate::handlers::helpers::{error_response, get_vector_collection_or_404};
use crate::types::ErrorResponse;
use crate::AppState;
#[utoipa::path(
post,
path = "/collections/{name}/points/raw",
tag = "points",
params(
("name" = String, Path, description = "Collection name")
),
request_body(content = String, content_type = "application/octet-stream", description = "VRB1 binary bulk format: header + packed u64 ids + packed f32 vectors"),
responses(
(status = 200, description = "Points upserted", body = Object),
(status = 400, description = "Malformed body or dimension mismatch", body = ErrorResponse),
(status = 404, description = "Collection not found", body = ErrorResponse)
)
)]
pub async fn upsert_points_raw(
State(state): State<Arc<AppState>>,
Path(name): Path<String>,
body: Bytes,
) -> impl IntoResponse {
let collection = match get_vector_collection_or_404(&state, &name) {
Ok(c) => c,
Err(resp) => return resp,
};
let batch = match vrb1::decode(&body) {
Ok(b) => b,
Err(err) => return error_response(StatusCode::BAD_REQUEST, err.to_string()),
};
let dimension = batch.dimension;
let ids = batch.ids;
let vectors = batch.vectors;
let result = tokio::task::spawn_blocking(move || {
collection.upsert_bulk_from_raw(&vectors, &ids, dimension, None)
})
.await;
upsert_result_to_response(&state, &name, result)
}