import * as fs from 'fs';
import * as path from 'path';
import { TOSClientWrapper, TOSClientConfig } from './tos-client.js';
import TOSService from './tos-service.js';

// 测试配置 - 请根据实际情况修改
const TEST_CONFIG: TOSClientConfig = {
  accessKeyId: process.env.TOS_ACCESS_KEY_ID || 'test-access-key',
  accessKeySecret: process.env.TOS_ACCESS_KEY_SECRET || 'test-secret-key',
  endpoint: 'tos-cn-beijing.volces.com',
  region: 'cn-beijing',
  bucketName: process.env.TOS_BUCKET_NAME || 'test-bucket',
  selfDomain: process.env.TOS_SELF_DOMAIN || 'test-domain.com'
};

class TOSClientTest {
  private tosClient: TOSClientWrapper;
  private testResults: { [key: string]: boolean } = {};

  constructor() {
    this.tosClient = new TOSClientWrapper(TEST_CONFIG);
  }

  /**
   * 创建测试文件
   */
  private createTestFile(): string {
    const testDir = path.join(process.cwd(), 'test-files');
    if (!fs.existsSync(testDir)) {
      fs.mkdirSync(testDir, { recursive: true });
    }
    
    const testFilePath = path.join(testDir, 'test-image.txt');
    const testContent = `测试文件内容\n创建时间: ${new Date().toISOString()}\n这是一个用于测试TOS上传功能的文件。`;
    
    fs.writeFileSync(testFilePath, testContent, 'utf-8');
    return testFilePath;
  }

  /**
   * 测试字符串上传
   */
  async testUploadString(): Promise<string | null> {
    console.log('\n🧪 测试字符串上传...');
    try {
      const testContent = `测试字符串内容 - ${Date.now()}`;
      const objectKey = `test/string-${Date.now()}.txt`;
      
      const url = await this.tosClient.uploadString(testContent, objectKey);
      console.log('✅ 字符串上传成功:', url);
      
      // 验证文件是否存在
      const exists = await this.tosClient.fileExists(objectKey);
      console.log('✅ 文件存在性验证:', exists);
      
      this.testResults['uploadString'] = true;
      return objectKey;
    } catch (error: any) {
      console.error('❌ 字符串上传失败:', error.message);
      this.testResults['uploadString'] = false;
      return null;
    }
  }

  /**
   * 测试本地文件上传
   */
  async testUploadFile(): Promise<string | null> {
    console.log('\n🧪 测试本地文件上传...');
    try {
      const testFilePath = this.createTestFile();
      const objectKey = `test/file-${Date.now()}.txt`;
      
      const url = await this.tosClient.uploadFile(testFilePath, objectKey);
      console.log('✅ 本地文件上传成功:', url);
      
      // 清理测试文件
      fs.unlinkSync(testFilePath);
      fs.rmdirSync(path.dirname(testFilePath));
      
      this.testResults['uploadFile'] = true;
      return objectKey;
    } catch (error: any) {
      console.error('❌ 本地文件上传失败:', error.message);
      this.testResults['uploadFile'] = false;
      return null;
    }
  }

  /**
   * 测试Buffer上传
   */
  async testUploadBuffer(): Promise<string | null> {
    console.log('\n🧪 测试Buffer上传...');
    try {
      const testBuffer = Buffer.from(`测试Buffer内容 - ${Date.now()}`, 'utf-8');
      const objectKey = `test/buffer-${Date.now()}.txt`;
      
      const url = await this.tosClient.uploadBytes(testBuffer, objectKey, 'text/plain');
      console.log('✅ Buffer上传成功:', url);
      
      this.testResults['uploadBuffer'] = true;
      return objectKey;
    } catch (error: any) {
      console.error('❌ Buffer上传失败:', error.message);
      this.testResults['uploadBuffer'] = false;
      return null;
    }
  }

  /**
   * 测试文件下载
   */
  async testDownloadFile(objectKey: string): Promise<void> {
    if (!objectKey) {
      console.log('\n⏭️  跳过文件下载测试 (没有可用的测试文件)');
      return;
    }

    console.log('\n🧪 测试文件下载...');
    try {
      const data = await this.tosClient.downloadFile(objectKey);
      console.log('✅ 文件下载成功, 大小:', data.length, '字节');
      console.log('📄 文件内容预览:', data.toString('utf-8').substring(0, 100) + '...');
      
      this.testResults['downloadFile'] = true;
    } catch (error: any) {
      console.error('❌ 文件下载失败:', error.message);
      this.testResults['downloadFile'] = false;
    }
  }

  /**
   * 测试文件信息获取
   */
  async testGetFileInfo(objectKey: string): Promise<void> {
    if (!objectKey) {
      console.log('\n⏭️  跳过文件信息测试 (没有可用的测试文件)');
      return;
    }

    console.log('\n🧪 测试获取文件信息...');
    try {
      const info = await this.tosClient.getFileInfo(objectKey);
      console.log('✅ 文件信息获取成功:', info);
      
      this.testResults['getFileInfo'] = true;
    } catch (error: any) {
      console.error('❌ 获取文件信息失败:', error.message);
      this.testResults['getFileInfo'] = false;
    }
  }

  /**
   * 测试生成签名URL
   */
  async testGenerateUrl(objectKey: string): Promise<void> {
    if (!objectKey) {
      console.log('\n⏭️  跳过URL生成测试 (没有可用的测试文件)');
      return;
    }

    console.log('\n🧪 测试生成签名URL...');
    try {
      const signedUrl = await this.tosClient.generateUrl(objectKey, 3600);
      console.log('✅ 签名URL生成成功:', signedUrl.substring(0, 100) + '...');
      
      const publicUrl = this.tosClient.getBaseUrl(objectKey);
      console.log('✅ 公开URL生成成功:', publicUrl);
      
      this.testResults['generateUrl'] = true;
    } catch (error: any) {
      console.error('❌ URL生成失败:', error.message);
      this.testResults['generateUrl'] = false;
    }
  }

  /**
   * 测试服务类方法
   */
  async testTOSService(): Promise<void> {
    console.log('\n🧪 测试TOS服务类...');
    try {
      // 测试上传文本
      const textUrl = await TOSService.uploadText('服务类测试内容', 'service-test.txt');
      console.log('✅ 服务类文本上传成功:', textUrl);
      
      // 测试上传Buffer
      const buffer = Buffer.from('服务类Buffer测试', 'utf-8');
      const bufferUrl = await TOSService.uploadBuffer(buffer, 'service-buffer-test.txt', 'text/plain');
      console.log('✅ 服务类Buffer上传成功:', bufferUrl);
      
      this.testResults['tosService'] = true;
    } catch (error: any) {
      console.error('❌ TOS服务类测试失败:', error.message);
      this.testResults['tosService'] = false;
    }
  }

  /**
   * 测试文件删除（清理测试文件）
   */
  async testDeleteFile(objectKey: string): Promise<void> {
    if (!objectKey) {
      console.log('\n⏭️  跳过文件删除测试 (没有可用的测试文件)');
      return;
    }

    console.log('\n🧪 测试文件删除...');
    try {
      const deleted = await this.tosClient.deleteFile(objectKey);
      console.log('✅ 文件删除成功:', deleted);
      
      // 验证文件是否已被删除
      const exists = await this.tosClient.fileExists(objectKey);
      console.log('✅ 删除验证 (应为false):', exists);
      
      this.testResults['deleteFile'] = true;
    } catch (error: any) {
      console.error('❌ 文件删除失败:', error.message);
      this.testResults['deleteFile'] = false;
    }
  }

  /**
   * 运行所有测试
   */
  async runAllTests(): Promise<void> {
    console.log('🚀 开始TOS客户端功能测试...');
    console.log('📋 测试配置:');
    console.log('   - Endpoint:', TEST_CONFIG.endpoint);
    console.log('   - Region:', TEST_CONFIG.region);
    console.log('   - Bucket:', TEST_CONFIG.bucketName);
    console.log('   - Domain:', TEST_CONFIG.selfDomain);

    let testObjectKey: string | null = null;

    // 执行各项测试
    testObjectKey = await this.testUploadString();
    await this.testUploadFile();
    const bufferObjectKey = await this.testUploadBuffer();
    
    // 使用上传的文件进行其他测试
    if (testObjectKey) {
      await this.testDownloadFile(testObjectKey);
      await this.testGetFileInfo(testObjectKey);
      await this.testGenerateUrl(testObjectKey);
    }
    
    // 测试服务类
    await this.testTOSService();
    
    // 清理测试文件
    if (testObjectKey) {
      await this.testDeleteFile(testObjectKey);
    }
    if (bufferObjectKey) {
      await this.testDeleteFile(bufferObjectKey);
    }

    // 输出测试结果
    this.printTestResults();
  }

  /**
   * 打印测试结果
   */
  private printTestResults(): void {
    console.log('\n📊 测试结果汇总:');
    console.log('=' .repeat(50));
    
    let passCount = 0;
    let totalCount = 0;
    
    Object.entries(this.testResults).forEach(([testName, result]) => {
      totalCount++;
      if (result) {
        passCount++;
        console.log(`✅ ${testName}: 通过`);
      } else {
        console.log(`❌ ${testName}: 失败`);
      }
    });
    
    console.log('=' .repeat(50));
    console.log(`📈 总体结果: ${passCount}/${totalCount} 测试通过`);
    
    if (passCount === totalCount) {
      console.log('🎉 所有测试都通过了！TOS客户端集成成功！');
    } else {
      console.log('⚠️  部分测试失败，请检查配置和网络连接。');
    }
  }
}

// 运行测试的函数
export async function runTOSTests(): Promise<void> {
  const tester = new TOSClientTest();
  await tester.runAllTests();
}

// 如果直接运行此文件，则执行测试
// if (require.main === module) {
//   runTOSTests().catch(error => {
//     console.error('测试执行失败:', error);
//     process.exit(1);
//   });
// }

export default TOSClientTest;