/**
 * 加密工具函数测试
 */

const {
  hashPassword,
  verifyPassword,
  generateToken,
  generateDeviceId,
  validateDeviceId,
  maskPhone,
  maskEmail,
  maskSensitiveData
} = require('../utils/crypto_utils');

// 测试密码加密和验证
async function testPasswordEncryption() {
  console.log('\n===== 测试密码加密和验证 =====');

  try {
    // 测试 1: 基本加密和验证
    const password = 'mySecurePassword123';
    const hashed = await hashPassword(password);
    console.log('✓ 密码加密成功:', hashed.substring(0, 20) + '...');

    // 验证正确密码
    const isValid = await verifyPassword(password, hashed);
    console.log('✓ 正确密码验证:', isValid ? '通过' : '失败');

    // 验证错误密码
    const isInvalid = await verifyPassword('wrongPassword', hashed);
    console.log('✓ 错误密码验证:', isInvalid ? '失败（不应该通过）' : '正确拒绝');

    // 测试 2: 相同密码生成不同哈希
    const hashed2 = await hashPassword(password);
    console.log('✓ 相同密码生成不同哈希:', hashed !== hashed2 ? '是' : '否');

    // 测试 3: 空密码处理
    try {
      await hashPassword('');
      console.log('✗ 空密码应该抛出错误');
    } catch (error) {
      console.log('✓ 空密码正确抛出错误');
    }

    return true;
  } catch (error) {
    console.error('✗ 密码加密测试失败:', error.message);
    return false;
  }
}

// 测试设备ID生成和验证
function testDeviceId() {
  console.log('\n===== 测试设备ID生成和验证 =====');

  try {
    // 测试 1: 生成设备ID
    const deviceId1 = generateDeviceId();
    console.log('✓ 生成设备ID:', deviceId1);

    // 测试 2: 验证有效设备ID
    const isValid = validateDeviceId(deviceId1);
    console.log('✓ 验证有效设备ID:', isValid ? '通过' : '失败');

    // 测试 3: 验证无效设备ID
    const invalidIds = [
      'invalid_id',
      'device_abc_123',
      '123456789',
      '',
      null,
      undefined
    ];

    let allInvalidRejected = true;
    for (const id of invalidIds) {
      if (validateDeviceId(id)) {
        console.log('✗ 无效ID未被拒绝:', id);
        allInvalidRejected = false;
      }
    }

    if (allInvalidRejected) {
      console.log('✓ 所有无效设备ID都被正确拒绝');
    }

    // 测试 4: 生成的ID唯一性
    const deviceId2 = generateDeviceId();
    console.log('✓ 生成的ID是唯一的:', deviceId1 !== deviceId2 ? '是' : '否');

    return true;
  } catch (error) {
    console.error('✗ 设备ID测试失败:', error.message);
    return false;
  }
}

// 测试数据脱敏
function testDataMasking() {
  console.log('\n===== 测试数据脱敏 =====');

  try {
    // 测试 1: 手机号脱敏
    const phone = '13800138000';
    const maskedPhone = maskPhone(phone);
    console.log('✓ 手机号脱敏:', phone, '->', maskedPhone);
    console.assert(maskedPhone === '138****8000', '手机号脱敏格式错误');

    // 测试 2: 邮箱脱敏
    const email = 'user@example.com';
    const maskedEmail = maskEmail(email);
    console.log('✓ 邮箱脱敏:', email, '->', maskedEmail);

    // 测试 3: 对象脱敏
    const sensitiveObj = {
      username: 'john',
      password: 'secret123',
      email: 'john@example.com',
      token: 'abc123xyz',
      normalField: 'public data'
    };

    const masked = maskSensitiveData(sensitiveObj);
    console.log('✓ 对象脱敏:');
    console.log('  原始:', sensitiveObj);
    console.log('  脱敏:', masked);

    // 验证敏感字段被屏蔽
    console.assert(masked.password === '***MASKED***', 'password未被屏蔽');
    console.assert(masked.token === '***MASKED***', 'token未被屏蔽');
    console.assert(masked.normalField === 'public data', '普通字段被修改');

    return true;
  } catch (error) {
    console.error('✗ 数据脱敏测试失败:', error.message);
    return false;
  }
}

// 测试Token生成
function testTokenGeneration() {
  console.log('\n===== 测试Token生成 =====');

  try {
    // 测试 1: 生成默认长度token
    const token1 = generateToken();
    console.log('✓ 生成默认token (64字符):', token1.substring(0, 20) + '...');
    console.assert(token1.length === 64, 'Token长度错误');

    // 测试 2: 生成指定长度token
    const token2 = generateToken(16);
    console.log('✓ 生成16字节token (32字符):', token2);
    console.assert(token2.length === 32, 'Token长度错误');

    // 测试 3: Token唯一性
    const token3 = generateToken();
    console.log('✓ Token唯一性:', token1 !== token3 ? '是' : '否');

    return true;
  } catch (error) {
    console.error('✗ Token生成测试失败:', error.message);
    return false;
  }
}

// 运行所有测试
async function runAllTests() {
  console.log('\n==================== 开始测试 ====================\n');

  const results = [];

  results.push(await testPasswordEncryption());
  results.push(testDeviceId());
  results.push(testDataMasking());
  results.push(testTokenGeneration());

  console.log('\n==================== 测试总结 ====================\n');

  const passed = results.filter(r => r).length;
  const total = results.length;

  console.log(`测试通过: ${passed}/${total}`);

  if (passed === total) {
    console.log('\n✓ 所有测试通过！\n');
    process.exit(0);
  } else {
    console.log('\n✗ 部分测试失败\n');
    process.exit(1);
  }
}

// 执行测试
if (require.main === module) {
  runAllTests().catch(error => {
    console.error('测试执行失败:', error);
    process.exit(1);
  });
}

module.exports = {
  testPasswordEncryption,
  testDeviceId,
  testDataMasking,
  testTokenGeneration
};
