import { presignR2Put } from "./presign-s3compat.js";
import { putObject } from "./r2-binding.js";
import { StorageError, assertExactStorageKey, assertPresignExpiry } from "./storage.js";
//#region src/storage-r2.ts
function headOf(o) {
	return {
		key: o.key,
		size: o.size,
		etag: o.etag,
		contentType: o.httpMetadata?.contentType,
		customMetadata: o.customMetadata,
		uploadedAt: o.uploaded?.getTime()
	};
}
/** CF R2 StorageAdapter — the mod-cms production backend. Wraps the existing putObject/presignR2Put leaves. */
function createR2Storage(options) {
	const { bucket, presign } = options;
	return {
		async put(key, body, opts) {
			const result = await putObject(bucket, key, body, {
				httpMetadata: {
					contentType: opts?.contentType,
					cacheControl: opts?.cacheControl
				},
				customMetadata: opts?.customMetadata
			});
			return {
				key: result.key,
				size: result.size,
				etag: result.etag
			};
		},
		async get(key) {
			const o = await bucket.get(key);
			if (!o) return null;
			return {
				...headOf(o),
				body: o.body
			};
		},
		async head(key) {
			const o = await bucket.head(key);
			return o ? headOf(o) : null;
		},
		async delete(key) {
			await bucket.delete(key);
		},
		async list(opts) {
			const res = await bucket.list({
				prefix: opts?.prefix,
				cursor: opts?.cursor,
				limit: opts?.limit
			});
			return {
				objects: res.objects.map(headOf),
				cursor: res.truncated ? res.cursor : void 0
			};
		},
		async presignPut(key, opts) {
			if (!presign) throw new StorageError("backend", "presignPut requires S3-API creds (createR2Storage was given no `presign`)");
			assertExactStorageKey(key);
			assertPresignExpiry(opts.expiresIn);
			try {
				const signed = await presignR2Put(presign, key, opts.contentType ?? "application/octet-stream", opts.expiresIn);
				return {
					url: signed.url,
					method: "PUT",
					headers: signed.headers,
					expiresIn: opts.expiresIn
				};
			} catch (e) {
				if (e.name === "InvalidPresignKeyError") throw new StorageError("invalid_key", e.message);
				throw e;
			}
		}
	};
}
//#endregion
export { StorageError, createR2Storage };
