/**
 * 테이블 타입관리 성능 테스트 스크립트
 * 최적화 전후 성능 비교용
 */

const axios = require("axios");

const BASE_URL = "http://localhost:3001/api";
const TEST_TABLE = "user_info"; // 테스트할 테이블명

// 성능 측정 함수
async function measurePerformance(name, fn) {
  const start = Date.now();
  try {
    const result = await fn();
    const end = Date.now();
    const duration = end - start;

    console.log(`✅ ${name}: ${duration}ms`);
    return { success: true, duration, result };
  } catch (error) {
    const end = Date.now();
    const duration = end - start;

    console.log(`❌ ${name}: ${duration}ms (실패: ${error.message})`);
    return { success: false, duration, error: error.message };
  }
}

// 테스트 함수들
const tests = {
  // 1. 테이블 목록 조회 성능
  async testTableList() {
    return await axios.get(`${BASE_URL}/table-management/tables`);
  },

  // 2. 컬럼 목록 조회 성능 (첫 페이지)
  async testColumnListFirstPage() {
    return await axios.get(
      `${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=1&size=50`
    );
  },

  // 3. 컬럼 목록 조회 성능 (큰 페이지)
  async testColumnListLargePage() {
    return await axios.get(
      `${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=1&size=200`
    );
  },

  // 4. 캐시 효과 테스트 (동일한 요청 반복)
  async testCacheEffect() {
    // 첫 번째 요청 (캐시 미스)
    await axios.get(
      `${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=1&size=50`
    );

    // 두 번째 요청 (캐시 히트)
    return await axios.get(
      `${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=1&size=50`
    );
  },

  // 5. 동시 요청 처리 성능
  async testConcurrentRequests() {
    const requests = Array(10)
      .fill()
      .map((_, i) =>
        axios.get(
          `${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=${i + 1}&size=20`
        )
      );

    return await Promise.all(requests);
  },
};

// 메인 테스트 실행
async function runPerformanceTests() {
  console.log("🚀 테이블 타입관리 성능 테스트 시작\n");
  console.log(`📊 테스트 대상: ${BASE_URL}`);
  console.log(`📋 테스트 테이블: ${TEST_TABLE}\n`);

  const results = {};

  // 각 테스트 실행
  for (const [testName, testFn] of Object.entries(tests)) {
    console.log(`\n--- ${testName} ---`);

    // 각 테스트를 3번 실행하여 평균 계산
    const runs = [];
    for (let i = 0; i < 3; i++) {
      const result = await measurePerformance(`실행 ${i + 1}`, testFn);
      runs.push(result);

      // 테스트 간 간격
      await new Promise((resolve) => setTimeout(resolve, 100));
    }

    // 성공한 실행들의 평균 시간 계산
    const successfulRuns = runs.filter((r) => r.success);
    if (successfulRuns.length > 0) {
      const avgDuration =
        successfulRuns.reduce((sum, r) => sum + r.duration, 0) /
        successfulRuns.length;
      const minDuration = Math.min(...successfulRuns.map((r) => r.duration));
      const maxDuration = Math.max(...successfulRuns.map((r) => r.duration));

      results[testName] = {
        average: Math.round(avgDuration),
        min: minDuration,
        max: maxDuration,
        successRate: (successfulRuns.length / runs.length) * 100,
      };

      console.log(
        `📈 평균: ${Math.round(avgDuration)}ms, 최소: ${minDuration}ms, 최대: ${maxDuration}ms`
      );
    } else {
      results[testName] = { error: "모든 테스트 실패" };
      console.log("❌ 모든 테스트 실패");
    }
  }

  // 결과 요약
  console.log("\n" + "=".repeat(50));
  console.log("📊 성능 테스트 결과 요약");
  console.log("=".repeat(50));

  for (const [testName, result] of Object.entries(results)) {
    if (result.error) {
      console.log(`❌ ${testName}: ${result.error}`);
    } else {
      console.log(
        `✅ ${testName}: ${result.average}ms (${result.min}-${result.max}ms, 성공률: ${result.successRate}%)`
      );
    }
  }

  // 성능 기준 평가
  console.log("\n" + "=".repeat(50));
  console.log("🎯 성능 기준 평가");
  console.log("=".repeat(50));

  const benchmarks = {
    testTableList: { good: 200, acceptable: 500 },
    testColumnListFirstPage: { good: 300, acceptable: 800 },
    testColumnListLargePage: { good: 500, acceptable: 1200 },
    testCacheEffect: { good: 50, acceptable: 150 },
    testConcurrentRequests: { good: 1000, acceptable: 3000 },
  };

  for (const [testName, result] of Object.entries(results)) {
    if (result.error) continue;

    const benchmark = benchmarks[testName];
    if (!benchmark) continue;

    let status = "🔴 느림";
    if (result.average <= benchmark.good) {
      status = "🟢 우수";
    } else if (result.average <= benchmark.acceptable) {
      status = "🟡 양호";
    }

    console.log(`${status} ${testName}: ${result.average}ms`);
  }

  console.log("\n✨ 성능 테스트 완료!");
}

// 에러 핸들링
process.on("unhandledRejection", (error) => {
  console.error("❌ 처리되지 않은 에러:", error.message);
  process.exit(1);
});

// 테스트 실행
if (require.main === module) {
  runPerformanceTests().catch(console.error);
}

module.exports = { runPerformanceTests, measurePerformance };
