/**
 * 性能监控属性测试
 * 
 * Property 13: 性能监控准确性
 * 
 * Validates: Requirements 8.1, 8.2
 * 
 * 测试目标：
 * - 验证性能监控数据的准确性
 * - 确保性能指标收集的完整性
 * - 验证性能警告机制的有效性
 * 
 * 最近修改：
 * - 2026-01-08: 注释规范优化 - 修正@author字段，更新版本号和修改记录 (修改者: moyin)
 * - 2026-01-08: 功能新增 - 创建性能监控属性测试 (修改者: assistant)
 * 
 * @author moyin
 * @version 1.0.1
 * @since 2026-01-08
 * @lastModified 2026-01-08
 */

import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AdminDatabaseController } from './admin_database.controller';
import { DatabaseManagementService } from './database_management.service';
import { AdminOperationLogService } from './admin_operation_log.service';
import { AdminOperationLogInterceptor } from './admin_operation_log.interceptor';
import { AdminDatabaseExceptionFilter } from './admin_database_exception.filter';
import { AdminGuard } from './admin.guard';
import { UserStatus } from '../user_mgmt/user_status.enum';
import {
  PropertyTestRunner,
  PropertyTestGenerators,
  PropertyTestAssertions,
  DEFAULT_PROPERTY_CONFIG
} from './admin_property_test.base';

describe('Property Test: 性能监控功能', () => {
  let app: INestApplication;
  let module: TestingModule;
  let controller: AdminDatabaseController;
  let performanceMetrics: any[] = [];
  let mockUsersService: any;
  let mockUserProfilesService: any;
  let mockZulipAccountsService: any;

  beforeAll(async () => {
    performanceMetrics = [];
    
    // 创建性能监控mock
    const createPerformanceAwareMock = (serviceName: string, methodName: string, baseDelay: number = 50) => {
      return jest.fn().mockImplementation(async (...args) => {
        const startTime = Date.now();
        
        // 模拟不同的执行时间
        const randomDelay = baseDelay + Math.random() * 100;
        await new Promise(resolve => setTimeout(resolve, randomDelay));
        
        const endTime = Date.now();
        const duration = endTime - startTime;
        
        // 记录性能指标
        performanceMetrics.push({
          service: serviceName,
          method: methodName,
          duration,
          timestamp: new Date().toISOString(),
          args: args.length
        });
        
        // 根据方法返回适当的mock数据
        if (methodName === 'findAll') {
          return [];
        } else if (methodName === 'count') {
          return 0;
        } else if (methodName === 'findOne' || methodName === 'findById') {
          if (serviceName === 'UsersService') {
            return { ...PropertyTestGenerators.generateUser(), id: BigInt(1) };
          } else if (serviceName === 'UserProfilesService') {
            return { ...PropertyTestGenerators.generateUserProfile(), id: BigInt(1) };
          } else {
            return { ...PropertyTestGenerators.generateZulipAccount(), id: '1' };
          }
        } else if (methodName === 'create') {
          if (serviceName === 'UsersService') {
            return { ...args[0], id: BigInt(1) };
          } else if (serviceName === 'UserProfilesService') {
            return { ...args[0], id: BigInt(1) };
          } else {
            return { ...args[0], id: '1' };
          }
        } else if (methodName === 'update') {
          if (serviceName === 'UsersService') {
            return { ...PropertyTestGenerators.generateUser(), ...args[1], id: args[0] };
          } else if (serviceName === 'UserProfilesService') {
            return { ...PropertyTestGenerators.generateUserProfile(), ...args[1], id: args[0] };
          } else {
            return { ...PropertyTestGenerators.generateZulipAccount(), ...args[1], id: args[0] };
          }
        } else if (methodName === 'findMany') {
          return { accounts: [], total: 0 };
        } else if (methodName === 'getStatusStatistics') {
          return { active: 0, inactive: 0, suspended: 0, error: 0, total: 0 };
        }
        
        return {};
      });
    };

    mockUsersService = {
      findAll: createPerformanceAwareMock('UsersService', 'findAll', 30),
      findOne: createPerformanceAwareMock('UsersService', 'findOne', 20),
      create: createPerformanceAwareMock('UsersService', 'create', 80),
      update: createPerformanceAwareMock('UsersService', 'update', 60),
      remove: createPerformanceAwareMock('UsersService', 'remove', 40),
      search: createPerformanceAwareMock('UsersService', 'search', 100),
      count: createPerformanceAwareMock('UsersService', 'count', 25)
    };

    mockUserProfilesService = {
      findAll: createPerformanceAwareMock('UserProfilesService', 'findAll', 35),
      findOne: createPerformanceAwareMock('UserProfilesService', 'findOne', 25),
      create: createPerformanceAwareMock('UserProfilesService', 'create', 90),
      update: createPerformanceAwareMock('UserProfilesService', 'update', 70),
      remove: createPerformanceAwareMock('UserProfilesService', 'remove', 45),
      findByMap: createPerformanceAwareMock('UserProfilesService', 'findByMap', 120),
      count: createPerformanceAwareMock('UserProfilesService', 'count', 30)
    };

    mockZulipAccountsService = {
      findMany: createPerformanceAwareMock('ZulipAccountsService', 'findMany', 40),
      findById: createPerformanceAwareMock('ZulipAccountsService', 'findById', 30),
      create: createPerformanceAwareMock('ZulipAccountsService', 'create', 100),
      update: createPerformanceAwareMock('ZulipAccountsService', 'update', 80),
      delete: createPerformanceAwareMock('ZulipAccountsService', 'delete', 50),
      batchUpdateStatus: createPerformanceAwareMock('ZulipAccountsService', 'batchUpdateStatus', 120),
      getStatusStatistics: createPerformanceAwareMock('ZulipAccountsService', 'getStatusStatistics', 60)
    };

    module = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({
          isGlobal: true,
          envFilePath: ['.env.test', '.env']
        })
      ],
      controllers: [AdminDatabaseController],
      providers: [
        DatabaseManagementService,
        {
          provide: AdminOperationLogService,
          useValue: {
            createLog: jest.fn().mockResolvedValue({}),
            queryLogs: jest.fn().mockResolvedValue({ logs: [], total: 0 }),
            getLogById: jest.fn().mockResolvedValue(null),
            getStatistics: jest.fn().mockResolvedValue({}),
            cleanupExpiredLogs: jest.fn().mockResolvedValue(0),
            getAdminOperationHistory: jest.fn().mockResolvedValue([]),
            getSensitiveOperations: jest.fn().mockResolvedValue({ logs: [], total: 0 })
          }
        },
        {
          provide: AdminOperationLogInterceptor,
          useValue: {
            intercept: jest.fn().mockImplementation((context, next) => next.handle())
          }
        },
        {
          provide: 'UsersService',
          useValue: mockUsersService
        },
        {
          provide: 'IUserProfilesService',
          useValue: mockUserProfilesService
        },
        {
          provide: 'ZulipAccountsService',
          useValue: mockZulipAccountsService
        }
      ]
    })
    .overrideGuard(AdminGuard)
    .useValue({ canActivate: () => true })
    .compile();

    app = module.createNestApplication();
    app.useGlobalFilters(new AdminDatabaseExceptionFilter());
    await app.init();

    controller = module.get<AdminDatabaseController>(AdminDatabaseController);
  });

  afterAll(async () => {
    await app.close();
  });

  beforeEach(() => {
    performanceMetrics.length = 0; // 清空性能指标
  });

  describe('Property 13: 性能监控准确性', () => {
    it('操作执行时间应该被准确记录', async () => {
      await PropertyTestRunner.runPropertyTest(
        '操作执行时间记录准确性',
        () => PropertyTestGenerators.generateUser(),
        async (userData) => {
          const startTime = Date.now();
          
          // 执行操作
          await controller.createUser({
            ...userData,
            status: UserStatus.ACTIVE
          });
          
          const endTime = Date.now();
          const totalDuration = endTime - startTime;
          
          // 验证性能指标被记录
          const createMetrics = performanceMetrics.filter(m => 
            m.service === 'UsersService' && m.method === 'create'
          );
          
          expect(createMetrics.length).toBeGreaterThan(0);
          
          const createMetric = createMetrics[0];
          expect(createMetric.duration).toBeGreaterThan(0);
          expect(createMetric.duration).toBeLessThan(totalDuration + 50); // 允许一些误差
          expect(createMetric.timestamp).toBeDefined();
          
          // 验证时间戳格式
          const timestamp = new Date(createMetric.timestamp);
          expect(timestamp.toISOString()).toBe(createMetric.timestamp);
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 20 }
      );
    });

    it('不同操作类型的性能指标应该被正确分类', async () => {
      await PropertyTestRunner.runPropertyTest(
        '操作类型性能分类',
        () => ({
          user: PropertyTestGenerators.generateUser(),
          profile: PropertyTestGenerators.generateUserProfile(),
          zulipAccount: PropertyTestGenerators.generateZulipAccount()
        }),
        async ({ user, profile, zulipAccount }) => {
          // 执行不同类型的操作
          await controller.getUserList(10, 0);
          await controller.createUser({ ...user, status: UserStatus.ACTIVE });
          await controller.getUserProfileList(10, 0);
          await controller.createUserProfile(profile);
          await controller.getZulipAccountList(10, 0);
          await controller.createZulipAccount(zulipAccount);
          
          // 验证不同服务的性能指标
          const userServiceMetrics = performanceMetrics.filter(m => m.service === 'UsersService');
          const profileServiceMetrics = performanceMetrics.filter(m => m.service === 'UserProfilesService');
          const zulipServiceMetrics = performanceMetrics.filter(m => m.service === 'ZulipAccountsService');
          
          expect(userServiceMetrics.length).toBeGreaterThan(0);
          expect(profileServiceMetrics.length).toBeGreaterThan(0);
          expect(zulipServiceMetrics.length).toBeGreaterThan(0);
          
          // 验证方法分类
          const createMethods = performanceMetrics.filter(m => m.method === 'create');
          const findAllMethods = performanceMetrics.filter(m => m.method === 'findAll');
          const countMethods = performanceMetrics.filter(m => m.method === 'count');
          
          expect(createMethods.length).toBe(3); // 三个create操作
          expect(findAllMethods.length).toBe(3); // 三个findAll操作
          expect(countMethods.length).toBe(3); // 三个count操作
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 15 }
      );
    });

    it('复杂查询的性能应该被正确监控', async () => {
      await PropertyTestRunner.runPropertyTest(
        '复杂查询性能监控',
        () => ({
          searchTerm: PropertyTestGenerators.generateUser().username.substring(0, 3),
          mapName: ['plaza', 'forest', 'beach'][Math.floor(Math.random() * 3)],
          limit: Math.floor(Math.random() * 50) + 10,
          offset: Math.floor(Math.random() * 100)
        }),
        async ({ searchTerm, mapName, limit, offset }) => {
          // 执行复杂查询操作
          await controller.searchUsers(searchTerm, limit);
          await controller.getUserProfilesByMap(mapName, limit, offset);
          await controller.getZulipAccountStatistics();
          
          // 验证复杂查询的性能指标
          const searchMetrics = performanceMetrics.filter(m => m.method === 'search');
          const mapQueryMetrics = performanceMetrics.filter(m => m.method === 'findByMap');
          const statsMetrics = performanceMetrics.filter(m => m.method === 'getStatusStatistics');
          
          expect(searchMetrics.length).toBeGreaterThan(0);
          expect(mapQueryMetrics.length).toBeGreaterThan(0);
          expect(statsMetrics.length).toBeGreaterThan(0);
          
          // 验证复杂查询通常耗时更长
          const searchDuration = searchMetrics[0].duration;
          const mapQueryDuration = mapQueryMetrics[0].duration;
          const statsDuration = statsMetrics[0].duration;
          
          expect(searchDuration).toBeGreaterThan(50); // 搜索操作基础延迟100ms
          expect(mapQueryDuration).toBeGreaterThan(70); // 地图查询基础延迟120ms
          expect(statsDuration).toBeGreaterThan(30); // 统计查询基础延迟60ms
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 15 }
      );
    });

    it('批量操作的性能应该被准确监控', async () => {
      await PropertyTestRunner.runPropertyTest(
        '批量操作性能监控',
        () => {
          const accountIds = Array.from({ length: Math.floor(Math.random() * 5) + 2 }, 
            (_, i) => `account_${i + 1}`);
          const targetStatus = ['active', 'inactive', 'suspended'][Math.floor(Math.random() * 3)];
          
          return { accountIds, targetStatus };
        },
        async ({ accountIds, targetStatus }) => {
          const startTime = Date.now();
          
          // 执行批量操作
          await controller.batchUpdateZulipAccountStatus({
            ids: accountIds,
            status: targetStatus as any,
            reason: '性能测试批量更新'
          });
          
          const endTime = Date.now();
          const totalDuration = endTime - startTime;
          
          // 验证批量操作的性能指标
          const updateMetrics = performanceMetrics.filter(m => 
            m.service === 'ZulipAccountsService' && m.method === 'update'
          );
          
          expect(updateMetrics.length).toBe(accountIds.length);
          
          // 验证每个更新操作的性能
          updateMetrics.forEach(metric => {
            expect(metric.duration).toBeGreaterThan(0);
            expect(metric.duration).toBeLessThan(200); // 单个操作不应超过200ms
          });
          
          // 验证总体性能合理性
          const totalServiceTime = updateMetrics.reduce((sum, m) => sum + m.duration, 0);
          expect(totalServiceTime).toBeLessThan(totalDuration + 100); // 允许一些并发优化
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 10 }
      );
    });

    it('性能异常应该被正确识别', async () => {
      await PropertyTestRunner.runPropertyTest(
        '性能异常识别',
        () => PropertyTestGenerators.generateUser(),
        async (userData) => {
          // 模拟慢查询（通过增加延迟）
          const originalFindOne = mockUsersService.findOne;
          mockUsersService.findOne = jest.fn().mockImplementation(async (...args) => {
            const startTime = Date.now();
            
            // 模拟异常慢的查询
            await new Promise(resolve => setTimeout(resolve, 300));
            
            const endTime = Date.now();
            const duration = endTime - startTime;
            
            performanceMetrics.push({
              service: 'UsersService',
              method: 'findOne',
              duration,
              timestamp: new Date().toISOString(),
              args: args.length,
              slow: duration > 200 // 标记为慢查询
            });
            
            return { ...PropertyTestGenerators.generateUser(), id: BigInt(1) };
          });
          
          // 执行操作
          await controller.getUserById('1');
          
          // 恢复原始mock
          mockUsersService.findOne = originalFindOne;
          
          // 验证慢查询被识别
          const slowQueries = performanceMetrics.filter(m => m.slow === true);
          expect(slowQueries.length).toBeGreaterThan(0);
          
          const slowQuery = slowQueries[0];
          expect(slowQuery.duration).toBeGreaterThan(200);
          expect(slowQuery.service).toBe('UsersService');
          expect(slowQuery.method).toBe('findOne');
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 10 }
      );
    });

    it('并发操作的性能应该被独立监控', async () => {
      await PropertyTestRunner.runPropertyTest(
        '并发操作性能监控',
        () => ({
          concurrentCount: Math.floor(Math.random() * 3) + 2 // 2-4个并发操作
        }),
        async ({ concurrentCount }) => {
          const promises = [];
          const startTime = Date.now();
          
          // 创建并发操作
          for (let i = 0; i < concurrentCount; i++) {
            const user = PropertyTestGenerators.generateUser();
            promises.push(
              controller.createUser({
                ...user,
                status: UserStatus.ACTIVE,
                username: `${user.username}_${i}` // 确保唯一性
              })
            );
          }
          
          // 等待所有操作完成
          await Promise.all(promises);
          
          const endTime = Date.now();
          const totalDuration = endTime - startTime;
          
          // 验证并发操作的性能指标
          const createMetrics = performanceMetrics.filter(m => 
            m.service === 'UsersService' && m.method === 'create'
          );
          
          expect(createMetrics.length).toBe(concurrentCount);
          
          // 验证每个操作都有独立的性能记录
          createMetrics.forEach((metric, index) => {
            expect(metric.duration).toBeGreaterThan(0);
            expect(metric.timestamp).toBeDefined();
            
            // 验证时间戳在合理范围内
            const metricTime = new Date(metric.timestamp).getTime();
            expect(metricTime).toBeGreaterThanOrEqual(startTime);
            expect(metricTime).toBeLessThanOrEqual(endTime);
          });
          
          // 验证并发执行的效率
          const avgDuration = createMetrics.reduce((sum, m) => sum + m.duration, 0) / concurrentCount;
          expect(totalDuration).toBeLessThan(avgDuration * concurrentCount * 1.2); // 并发应该有一定效率提升
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 10 }
      );
    });

    it('性能统计数据应该准确计算', async () => {
      await PropertyTestRunner.runPropertyTest(
        '性能统计准确性',
        () => ({
          operationCount: Math.floor(Math.random() * 8) + 3 // 3-10个操作
        }),
        async ({ operationCount }) => {
          // 执行多个操作
          for (let i = 0; i < operationCount; i++) {
            await controller.getUserList(10, i * 10);
          }
          
          // 计算性能统计
          const findAllMetrics = performanceMetrics.filter(m => 
            m.service === 'UsersService' && m.method === 'findAll'
          );
          
          expect(findAllMetrics.length).toBe(operationCount);
          
          // 计算统计数据
          const durations = findAllMetrics.map(m => m.duration);
          const totalDuration = durations.reduce((sum, d) => sum + d, 0);
          const avgDuration = totalDuration / durations.length;
          const minDuration = Math.min(...durations);
          const maxDuration = Math.max(...durations);
          
          // 验证统计数据合理性
          expect(totalDuration).toBeGreaterThan(0);
          expect(avgDuration).toBeGreaterThan(0);
          expect(avgDuration).toBeGreaterThanOrEqual(minDuration);
          expect(avgDuration).toBeLessThanOrEqual(maxDuration);
          expect(minDuration).toBeLessThanOrEqual(maxDuration);
          
          // 验证平均值在合理范围内（基础延迟30ms + 随机100ms）
          expect(avgDuration).toBeGreaterThan(20);
          expect(avgDuration).toBeLessThan(200);
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 15 }
      );
    });

    it('性能监控不应该显著影响操作性能', async () => {
      await PropertyTestRunner.runPropertyTest(
        '性能监控开销验证',
        () => PropertyTestGenerators.generateUser(),
        async (userData) => {
          const iterations = 5;
          const durations = [];
          
          // 执行多次相同操作
          for (let i = 0; i < iterations; i++) {
            const startTime = Date.now();
            
            await controller.createUser({
              ...userData,
              status: UserStatus.ACTIVE,
              username: `${userData.username}_${i}`
            });
            
            const endTime = Date.now();
            durations.push(endTime - startTime);
          }
          
          // 验证性能一致性
          const avgDuration = durations.reduce((sum, d) => sum + d, 0) / durations.length;
          const maxVariation = Math.max(...durations) - Math.min(...durations);
          
          // 性能变化不应该太大（监控开销应该很小）
          expect(maxVariation).toBeLessThan(avgDuration * 0.5); // 变化不超过平均值的50%
          
          // 验证所有操作都被监控
          const createMetrics = performanceMetrics.filter(m => 
            m.service === 'UsersService' && m.method === 'create'
          );
          
          expect(createMetrics.length).toBe(iterations);
        },
        { ...DEFAULT_PROPERTY_CONFIG, iterations: 10 }
      );
    });
  });
});