/**
 * Zulip账号关联数据模块测试
 * 
 * 功能描述：
 * - 测试动态模块配置的正确性
 * - 验证数据库和内存模式的切换逻辑
 * - 测试依赖注入配置的完整性
 * - 验证环境自适应功能
 * 
 * 测试范围：
 * - forDatabase()方法的模块配置
 * - forMemory()方法的模块配置
 * - forRoot()方法的自动选择逻辑
 * - isDatabaseConfigured()函数的环境检测
 * 
 * 最近修改：
 * - 2026-01-12: 代码规范优化 - 创建测试文件，确保模块配置逻辑的测试覆盖 (修改者: moyin)
 * - 2026-01-12: 代码规范优化 - 修复测试依赖注入问题，简化集成测试 (修改者: moyin)
 * 
 * @author moyin
 * @version 1.0.1
 * @since 2026-01-12
 * @lastModified 2026-01-12
 */

import { Test, TestingModule } from '@nestjs/testing';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CacheModule } from '@nestjs/cache-manager';
import { ZulipAccountsModule } from './zulip_accounts.module';
import { ZulipAccounts } from './zulip_accounts.entity';
import { ZulipAccountsRepository } from './zulip_accounts.repository';
import { ZulipAccountsMemoryRepository } from './zulip_accounts_memory.repository';
import { ZulipAccountsService } from './zulip_accounts.service';
import { ZulipAccountsMemoryService } from './zulip_accounts_memory.service';
import { AppLoggerService } from '../../utils/logger/logger.service';
import { REQUIRED_DB_ENV_VARS } from './zulip_accounts.constants';

describe('ZulipAccountsModule', () => {
  let originalEnv: NodeJS.ProcessEnv;

  beforeEach(() => {
    // 保存原始环境变量
    originalEnv = { ...process.env };
  });

  afterEach(() => {
    // 恢复原始环境变量
    process.env = originalEnv;
  });

  describe('forDatabase()', () => {
    it('should create database module with correct configuration', () => {
      const module = ZulipAccountsModule.forDatabase();

      expect(module).toBeDefined();
      expect(module.module).toBe(ZulipAccountsModule);
      expect(module.imports).toHaveLength(2);
      expect(module.providers).toHaveLength(3);
      expect(module.exports).toHaveLength(4);
    });

    it('should include TypeORM configuration for ZulipAccounts entity', () => {
      const module = ZulipAccountsModule.forDatabase();
      
      // 检查是否包含TypeORM模块配置
      const typeOrmModule = module.imports?.find(imp => 
        imp && typeof imp === 'object' && 'module' in imp
      );
      expect(typeOrmModule).toBeDefined();
    });

    it('should include CacheModule with correct configuration', () => {
      const module = ZulipAccountsModule.forDatabase();
      
      // 检查是否包含缓存模块
      const cacheModule = module.imports?.find(imp => 
        imp && typeof imp === 'object' && 'module' in imp
      );
      expect(cacheModule).toBeDefined();
    });

    it('should provide ZulipAccountsRepository', () => {
      const module = ZulipAccountsModule.forDatabase();
      
      expect(module.providers).toContain(ZulipAccountsRepository);
    });

    it('should provide AppLoggerService', () => {
      const module = ZulipAccountsModule.forDatabase();
      
      expect(module.providers).toContain(AppLoggerService);
    });

    it('should provide ZulipAccountsService with correct token', () => {
      const module = ZulipAccountsModule.forDatabase();
      
      const serviceProvider = module.providers?.find(provider => 
        typeof provider === 'object' && 
        provider !== null && 
        'provide' in provider && 
        provider.provide === 'ZulipAccountsService'
      );
      
      expect(serviceProvider).toBeDefined();
      expect((serviceProvider as any).useClass).toBe(ZulipAccountsService);
    });

    it('should export all required services', () => {
      const module = ZulipAccountsModule.forDatabase();
      
      expect(module.exports).toContain(ZulipAccountsRepository);
      expect(module.exports).toContain('ZulipAccountsService');
      expect(module.exports).toContain(TypeOrmModule);
      expect(module.exports).toContain(AppLoggerService);
    });
  });

  describe('forMemory()', () => {
    it('should create memory module with correct configuration', () => {
      const module = ZulipAccountsModule.forMemory();

      expect(module).toBeDefined();
      expect(module.module).toBe(ZulipAccountsModule);
      expect(module.imports).toHaveLength(1);
      expect(module.providers).toHaveLength(3);
      expect(module.exports).toHaveLength(3);
    });

    it('should include CacheModule with memory-optimized configuration', () => {
      const module = ZulipAccountsModule.forMemory();
      
      // 检查是否包含缓存模块
      expect(module.imports).toHaveLength(1);
    });

    it('should provide AppLoggerService', () => {
      const module = ZulipAccountsModule.forMemory();
      
      expect(module.providers).toContain(AppLoggerService);
    });

    it('should provide ZulipAccountsRepository with memory implementation', () => {
      const module = ZulipAccountsModule.forMemory();
      
      const repositoryProvider = module.providers?.find(provider => 
        typeof provider === 'object' && 
        provider !== null && 
        'provide' in provider && 
        provider.provide === 'ZulipAccountsRepository'
      );
      
      expect(repositoryProvider).toBeDefined();
      expect((repositoryProvider as any).useClass).toBe(ZulipAccountsMemoryRepository);
    });

    it('should provide ZulipAccountsService with memory implementation', () => {
      const module = ZulipAccountsModule.forMemory();
      
      const serviceProvider = module.providers?.find(provider => 
        typeof provider === 'object' && 
        provider !== null && 
        'provide' in provider && 
        provider.provide === 'ZulipAccountsService'
      );
      
      expect(serviceProvider).toBeDefined();
      expect((serviceProvider as any).useClass).toBe(ZulipAccountsMemoryService);
    });

    it('should export memory-specific services', () => {
      const module = ZulipAccountsModule.forMemory();
      
      expect(module.exports).toContain('ZulipAccountsRepository');
      expect(module.exports).toContain('ZulipAccountsService');
      expect(module.exports).toContain(AppLoggerService);
      expect(module.exports).not.toContain(TypeOrmModule);
    });
  });

  describe('forRoot()', () => {
    it('should return database module when all required env vars are set', () => {
      // 设置所有必需的环境变量
      REQUIRED_DB_ENV_VARS.forEach(varName => {
        process.env[varName] = 'test_value';
      });

      const module = ZulipAccountsModule.forRoot();
      
      // 应该返回数据库模式的配置
      expect(module.imports).toHaveLength(2); // TypeORM + Cache
      expect(module.providers).toHaveLength(3);
      expect(module.exports).toContain(TypeOrmModule);
    });

    it('should return memory module when some required env vars are missing', () => {
      // 清除所有环境变量
      REQUIRED_DB_ENV_VARS.forEach(varName => {
        delete process.env[varName];
      });

      const module = ZulipAccountsModule.forRoot();
      
      // 应该返回内存模式的配置
      expect(module.imports).toHaveLength(1); // 只有Cache
      expect(module.providers).toHaveLength(3);
      expect(module.exports).not.toContain(TypeOrmModule);
    });

    it('should return memory module when env vars are empty strings', () => {
      // 设置空字符串环境变量
      REQUIRED_DB_ENV_VARS.forEach(varName => {
        process.env[varName] = '';
      });

      const module = ZulipAccountsModule.forRoot();
      
      // 应该返回内存模式的配置
      expect(module.imports).toHaveLength(1);
      expect(module.exports).not.toContain(TypeOrmModule);
    });

    it('should return database module when all env vars have valid values', () => {
      // 设置有效的环境变量值
      process.env.DB_HOST = 'localhost';
      process.env.DB_PORT = '3306';
      process.env.DB_USERNAME = 'user';
      process.env.DB_PASSWORD = 'password';
      process.env.DB_DATABASE = 'testdb';

      const module = ZulipAccountsModule.forRoot();
      
      // 应该返回数据库模式的配置
      expect(module.imports).toHaveLength(2);
      expect(module.exports).toContain(TypeOrmModule);
    });
  });

  describe('isDatabaseConfigured() function behavior', () => {
    it('should detect complete database configuration', () => {
      // 设置完整的数据库配置
      REQUIRED_DB_ENV_VARS.forEach(varName => {
        process.env[varName] = 'valid_value';
      });

      const module = ZulipAccountsModule.forRoot();
      
      // 验证返回的是数据库模式
      expect(module.exports).toContain(TypeOrmModule);
    });

    it('should detect incomplete database configuration', () => {
      // 只设置部分环境变量
      if (REQUIRED_DB_ENV_VARS.length > 1) {
        process.env[REQUIRED_DB_ENV_VARS[0]] = 'value1';
        // 删除其他变量确保不完整
        for (let i = 1; i < REQUIRED_DB_ENV_VARS.length; i++) {
          delete process.env[REQUIRED_DB_ENV_VARS[i]];
        }
      }

      const module = ZulipAccountsModule.forRoot();
      
      // 验证返回的是内存模式
      expect(module.exports).not.toContain(TypeOrmModule);
    });

    it('should handle undefined environment variables', () => {
      // 确保所有必需变量都未定义
      REQUIRED_DB_ENV_VARS.forEach(varName => {
        delete process.env[varName];
      });

      const module = ZulipAccountsModule.forRoot();
      
      // 验证返回的是内存模式
      expect(module.exports).not.toContain(TypeOrmModule);
    });
  });

  describe('module integration', () => {
    it('should create module configuration without errors', () => {
      expect(() => ZulipAccountsModule.forDatabase()).not.toThrow();
      expect(() => ZulipAccountsModule.forMemory()).not.toThrow();
      expect(() => ZulipAccountsModule.forRoot()).not.toThrow();
    });

    it('should have different configurations for database and memory modes', () => {
      const databaseModule = ZulipAccountsModule.forDatabase();
      const memoryModule = ZulipAccountsModule.forMemory();

      expect(databaseModule.imports?.length).toBeGreaterThan(memoryModule.imports?.length || 0);
      expect(databaseModule.exports).toContain(TypeOrmModule);
      expect(memoryModule.exports).not.toContain(TypeOrmModule);
    });

    it('should provide consistent service interfaces', () => {
      const databaseModule = ZulipAccountsModule.forDatabase();
      const memoryModule = ZulipAccountsModule.forMemory();

      expect(databaseModule.exports).toContain('ZulipAccountsService');
      expect(memoryModule.exports).toContain('ZulipAccountsService');
      expect(databaseModule.exports).toContain(AppLoggerService);
      expect(memoryModule.exports).toContain(AppLoggerService);
    });
  });

  describe('error handling', () => {
    it('should handle missing REQUIRED_DB_ENV_VARS constant gracefully', () => {
      // 这个测试确保即使常量有问题，模块仍能工作
      expect(() => {
        ZulipAccountsModule.forRoot();
      }).not.toThrow();
    });

    it('should handle null/undefined environment values', () => {
      // 设置一些环境变量为null（通过删除后重新设置）
      REQUIRED_DB_ENV_VARS.forEach(varName => {
        delete process.env[varName];
        (process.env as any)[varName] = null;
      });

      expect(() => {
        ZulipAccountsModule.forRoot();
      }).not.toThrow();
    });
  });
});