import {Readable as ReadableStream} from 'node:stream';
import lowercaseKeys from 'lowercase-keys';

export default class Response extends ReadableStream {
	statusCode;
	headers;
	body;
	url;
	complete;

	constructor({statusCode, headers, body, url}) {
		if (typeof statusCode !== 'number') {
			throw new TypeError('Argument `statusCode` should be a number');
		}

		if (typeof headers !== 'object') {
			throw new TypeError('Argument `headers` should be an object');
		}

		if (!(body instanceof Uint8Array)) {
			throw new TypeError('Argument `body` should be a buffer');
		}

		if (typeof url !== 'string') {
			throw new TypeError('Argument `url` should be a string');
		}

		let bodyPushed = false;
		super({
			read() {
				// Push body on first read, end stream on second read.
				// This allows listeners to attach before data flows through pipes.
				if (!bodyPushed) {
					bodyPushed = true;
					this.push(body);
					return;
				}

				this.push(null);
			},
		});

		this.statusCode = statusCode;
		this.headers = lowercaseKeys(headers);
		this.body = body;
		this.url = url;
		this.complete = true;
	}
}
