import { ErrorFactory } from '../../../exceptions/ZintrustError.js';
import { Cloudflare } from '../../../config/cloudflare.js';
import { S3Driver } from '../drivers/S3.js';
const resolveWorkersBucket = (config) => {
    const binding = Cloudflare.getR2Binding(config.binding);
    if (binding === null || typeof binding.createMultipartUpload !== 'function') {
        throw ErrorFactory.createConfigError('R2 multipart requires a Workers R2 binding (set config.binding or R2_BUCKET/R2/BUCKET).');
    }
    return binding;
};
export const R2Driver = Object.freeze({
    async createMultipartUpload(config, key, options) {
        const bucket = resolveWorkersBucket(config);
        const upload = await bucket.createMultipartUpload(key, options);
        return { key: upload.key ?? key, uploadId: upload.uploadId };
    },
    async uploadPart(config, key, uploadId, partNumber, value, options) {
        const bucket = resolveWorkersBucket(config);
        const upload = bucket.resumeMultipartUpload(key, uploadId);
        return upload.uploadPart(partNumber, value, options);
    },
    async completeMultipartUpload(config, key, uploadId, uploadedParts) {
        const bucket = resolveWorkersBucket(config);
        const upload = bucket.resumeMultipartUpload(key, uploadId);
        await upload.complete(uploadedParts);
        return R2Driver.url(config, key);
    },
    async abortMultipartUpload(config, key, uploadId) {
        const bucket = resolveWorkersBucket(config);
        const upload = bucket.resumeMultipartUpload(key, uploadId);
        await upload.abort();
    },
    async put(config, key, content) {
        if (typeof config.endpoint !== 'string' || config.endpoint.trim() === '') {
            throw ErrorFactory.createConfigError('R2: missing endpoint');
        }
        // Delegate to S3Driver using path-style endpoint
        const s3Config = {
            bucket: config.bucket,
            region: config.region ?? 'auto',
            accessKeyId: config.accessKeyId,
            secretAccessKey: config.secretAccessKey,
            endpoint: config.endpoint,
            usePathStyle: true,
        };
        return S3Driver.put(s3Config, key, content);
    },
    async get(config, key) {
        const s3Config = {
            bucket: config.bucket,
            region: config.region ?? 'auto',
            accessKeyId: config.accessKeyId,
            secretAccessKey: config.secretAccessKey,
            endpoint: config.endpoint,
            usePathStyle: true,
        };
        return S3Driver.get(s3Config, key);
    },
    async exists(config, key) {
        const s3Config = {
            bucket: config.bucket,
            region: config.region ?? 'auto',
            accessKeyId: config.accessKeyId,
            secretAccessKey: config.secretAccessKey,
            endpoint: config.endpoint,
            usePathStyle: true,
        };
        return S3Driver.exists(s3Config, key);
    },
    async delete(config, key) {
        const s3Config = {
            bucket: config.bucket,
            region: config.region ?? 'auto',
            accessKeyId: config.accessKeyId,
            secretAccessKey: config.secretAccessKey,
            endpoint: config.endpoint,
            usePathStyle: true,
        };
        return S3Driver.delete(s3Config, key);
    },
    url(config, key) {
        if (config.endpoint !== undefined && config.endpoint.trim() !== '') {
            return `${config.endpoint.replace(/\/$/, '')}/${config.bucket}/${key}`;
        }
        return `https://${config.bucket}.r2.cloudflarestorage.com/${key}`;
    },
    tempUrl(config, key, options) {
        if (typeof config.endpoint !== 'string' || config.endpoint.trim() === '') {
            throw ErrorFactory.createConfigError('R2: missing endpoint');
        }
        const s3Config = {
            bucket: config.bucket,
            region: config.region ?? 'auto',
            accessKeyId: config.accessKeyId,
            secretAccessKey: config.secretAccessKey,
            endpoint: config.endpoint,
            usePathStyle: true,
        };
        return S3Driver.tempUrl(s3Config, key, options);
    },
});
export default R2Driver;
