#!/usr/bin/env node

/**
 * MinIO配置测试脚本
 * 基于用户提供的具体配置进行测试
 */

const { S3 } = require('@aws-sdk/client-s3');
const fs = require('fs');
const path = require('path');

async function testMinIOConfig() {
	console.log('🔍 开始测试MinIO配置...\n');

	// 用户提供的配置
	const config = {
		endpoint: 'http://localhost:9000',
		region: 'us-east-1',
		credentials: {
			accessKeyId: '7Nt7OyHkwIoo3zvSKdnc',
			secretAccessKey: 'EZ0cyrjJAsabTLNSqWcU47LURMppBW2kka3LuXzb',
		},
		forcePathStyle: true,
	};

	const bucketName = 'test123';
	const uploadDir = '/opt/projects/nice/uploads';

	console.log('📋 配置信息:');
	console.log(`   Endpoint: ${config.endpoint}`);
	console.log(`   Region: ${config.region}`);
	console.log(`   Bucket: ${bucketName}`);
	console.log(`   Upload Dir: ${uploadDir}`);
	console.log(`   Access Key: ${config.credentials.accessKeyId}`);
	console.log(`   Force Path Style: ${config.forcePathStyle}`);
	console.log();

	try {
		const s3Client = new S3(config);

		// 1. 测试基本连接和认证
		console.log('📡 测试连接和认证...');
		try {
			const buckets = await s3Client.listBuckets();
			console.log('✅ 连接和认证成功！');
			console.log(`📂 现有存储桶: ${buckets.Buckets?.map((b) => b.Name).join(', ') || '无'}`);
		} catch (error) {
			console.log('❌ 连接失败:', error.message);
			if (error.message.includes('ECONNREFUSED')) {
				console.log('💡 提示: MinIO服务可能未运行，请检查localhost:9000是否可访问');
			} else if (error.message.includes('Invalid')) {
				console.log('💡 提示: 检查访问密钥和密钥是否正确');
			}
			return false;
		}

		// 2. 检查目标存储桶
		console.log(`\n🪣 检查存储桶 "${bucketName}"...`);
		let bucketExists = false;
		try {
			await s3Client.headBucket({ Bucket: bucketName });
			console.log(`✅ 存储桶 "${bucketName}" 存在并可访问`);
			bucketExists = true;
		} catch (error) {
			if (error.name === 'NotFound') {
				console.log(`❌ 存储桶 "${bucketName}" 不存在`);
				console.log('🔧 尝试创建存储桶...');
				try {
					await s3Client.createBucket({ Bucket: bucketName });
					console.log(`✅ 存储桶 "${bucketName}" 创建成功`);
					bucketExists = true;
				} catch (createError) {
					console.log(`❌ 创建存储桶失败: ${createError.message}`);
					return false;
				}
			} else {
				console.log(`❌ 检查存储桶时出错: ${error.message}`);
				return false;
			}
		}

		if (!bucketExists) {
			return false;
		}

		// 3. 检查上传目录
		console.log(`\n📁 检查上传目录 "${uploadDir}"...`);
		try {
			if (!fs.existsSync(uploadDir)) {
				console.log('📁 上传目录不存在，正在创建...');
				fs.mkdirSync(uploadDir, { recursive: true });
				console.log('✅ 上传目录创建成功');
			} else {
				console.log('✅ 上传目录存在');
			}
		} catch (error) {
			console.log(`❌ 检查/创建上传目录失败: ${error.message}`);
		}

		// 4. 测试文件上传
		console.log('\n📤 测试文件上传...');
		const testFileName = `test-upload-${Date.now()}.txt`;
		const testContent = `这是一个测试文件
创建时间: ${new Date().toISOString()}
用户: nice1234
MinIO测试成功！`;

		try {
			await s3Client.putObject({
				Bucket: bucketName,
				Key: testFileName,
				Body: testContent,
				ContentType: 'text/plain',
				Metadata: {
					'test-type': 'config-validation',
					'created-by': 'test-script',
				},
			});
			console.log(`✅ 文件上传成功: ${testFileName}`);
		} catch (error) {
			console.log(`❌ 文件上传失败: ${error.message}`);
			console.log('错误详情:', error);
			return false;
		}

		// 5. 测试文件下载验证
		console.log('\n📥 测试文件下载验证...');
		try {
			const result = await s3Client.getObject({
				Bucket: bucketName,
				Key: testFileName,
			});

			// 读取流内容
			const chunks = [];
			for await (const chunk of result.Body) {
				chunks.push(chunk);
			}
			const downloadedContent = Buffer.concat(chunks).toString();

			if (downloadedContent === testContent) {
				console.log('✅ 文件下载验证成功，内容一致');
			} else {
				console.log('❌ 文件内容不一致');
				return false;
			}
		} catch (error) {
			console.log(`❌ 文件下载失败: ${error.message}`);
			return false;
		}

		// 6. 测试分片上传
		console.log('\n🔄 测试分片上传功能...');
		const multipartKey = `multipart-test-${Date.now()}.dat`;
		try {
			const multipartUpload = await s3Client.createMultipartUpload({
				Bucket: bucketName,
				Key: multipartKey,
				Metadata: {
					'test-type': 'multipart-upload',
				},
			});
			console.log(`✅ 分片上传初始化成功: ${multipartUpload.UploadId}`);

			// 清理测试
			await s3Client.abortMultipartUpload({
				Bucket: bucketName,
				Key: multipartKey,
				UploadId: multipartUpload.UploadId,
			});
			console.log('✅ 分片上传测试完成并清理');
		} catch (error) {
			console.log(`❌ 分片上传测试失败: ${error.message}`);
			return false;
		}

		// 7. 列出存储桶中的文件
		console.log('\n📂 列出存储桶中的文件...');
		try {
			const listResult = await s3Client.listObjectsV2({
				Bucket: bucketName,
				MaxKeys: 10,
			});

			console.log(`✅ 存储桶中共有 ${listResult.KeyCount || 0} 个文件`);
			if (listResult.Contents && listResult.Contents.length > 0) {
				console.log('最近的文件:');
				listResult.Contents.slice(-5).forEach((obj, index) => {
					const size = obj.Size < 1024 ? `${obj.Size}B` : `${Math.round(obj.Size / 1024)}KB`;
					console.log(`   ${index + 1}. ${obj.Key} (${size})`);
				});
			}
		} catch (error) {
			console.log(`❌ 列出文件失败: ${error.message}`);
		}

		// 8. 清理测试文件
		console.log('\n🧹 清理测试文件...');
		try {
			await s3Client.deleteObject({
				Bucket: bucketName,
				Key: testFileName,
			});
			console.log('✅ 测试文件清理完成');
		} catch (error) {
			console.log(`⚠️  清理测试文件失败: ${error.message}`);
		}

		console.log('\n🎉 所有测试通过！您的MinIO配置完全正确！');
		console.log('\n📝 配置摘要:');
		console.log('- ✅ 连接正常');
		console.log('- ✅ 认证有效');
		console.log('- ✅ 存储桶可用');
		console.log('- ✅ 文件上传/下载正常');
		console.log('- ✅ 分片上传支持');
		console.log('\n💡 您可以在应用中使用这些配置：');
		console.log('STORAGE_TYPE=s3');
		console.log(`UPLOAD_DIR=${uploadDir}`);
		console.log(`S3_ENDPOINT=${config.endpoint}`);
		console.log(`S3_REGION=${config.region}`);
		console.log(`S3_BUCKET=${bucketName}`);
		console.log(`S3_ACCESS_KEY_ID=${config.credentials.accessKeyId}`);
		console.log('S3_SECRET_ACCESS_KEY=***');
		console.log('S3_FORCE_PATH_STYLE=true');

		return true;
	} catch (error) {
		console.log(`❌ 测试过程中发生未预期错误: ${error.message}`);
		console.log('错误堆栈:', error.stack);
		return false;
	}
}

// 主函数
async function main() {
	console.log('🚀 MinIO S3存储配置测试\n');

	// 检查依赖
	try {
		require('@aws-sdk/client-s3');
	} catch (error) {
		console.log('❌ 缺少必要依赖 @aws-sdk/client-s3');
		console.log('请运行: npm install @aws-sdk/client-s3');
		process.exit(1);
	}

	const success = await testMinIOConfig();

	if (success) {
		console.log('\n✅ 测试完成：MinIO配置正确，可以正常使用！');
		process.exit(0);
	} else {
		console.log('\n❌ 测试失败：请检查上述错误并修复配置');
		process.exit(1);
	}
}

main().catch((error) => {
	console.error('❌ 脚本执行失败:', error);
	process.exit(1);
});
