// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use std::io::Error as IoError;

use serde::Deserialize;
use tokio::io::{BufReader, AsyncReadExt};
use quinn::RecvStream;

use super::super::{Error, QuicConnection, SIZE_LIMIT, vu30::{Vu30, AsyncReadVu30, ReadError}, init::Reader, super::serp};

pub struct Receiver {
	stream: BufReader<RecvStream>,
	buf: Vec<u8>,
	conn: QuicConnection,
}

impl Receiver {
	pub(super) fn new(stream: RecvStream, conn: QuicConnection) -> Receiver {
		Receiver { stream: BufReader::new(stream), buf: Vec::new(), conn }
	}

	pub async fn recv<'de, M: Deserialize<'de>>(&'de mut self) -> Result<M, Error> {
		self.recv_with_limit(SIZE_LIMIT).await
	}

	pub async fn recv_with_limit<'de, M: Deserialize<'de>>(&'de mut self, size_limit: usize) -> Result<M, Error> {
		self.buf.clear();
		self.stream.read_into_bytes(&mut self.buf, size_limit).await.map_err(|err| err.into_error(&self.conn))?;
		serp::deserialise(&self.buf, size_limit)
	}
}

impl Reader for Receiver {
	async fn read_exact(&mut self, data: &mut [u8]) -> Result<(), Error> {
		// Not sure what the return type is for, the documentation doesn't mention it
		let _x: usize = self.stream.read_exact(data).await.map_err(|_: IoError| &self.conn)?;
		Ok(())
	}

	async fn read_vu30(&mut self) -> Result<Vu30, Error> {
		Ok(self.stream.read_vu30().await.map_err(|()| &self.conn)?)
	}

	async fn read_bytes(&mut self) -> Result<Vec<u8>, (Error, ReadError)> {
		self.stream.read_bytes(SIZE_LIMIT).await.map_err(|err| (err.clone().into_error(&self.conn), err))
	}

	async fn read_string(&mut self) -> Result<String, Error> {
		self.stream.read_string(SIZE_LIMIT).await.map_err(|err| err.into_error(&self.conn))
	}
}
