'use strict';

/**
 * tests/helpers.js — генерация безопасных тестовых CIDR.
 *
 * Правила:
 *   1. Используем «кривые» публичные диапазоны — маловероятно в реальной жизни.
 *   2. Перед тестом проверяем что в БД нет реальных записей с таким CIDR.
 *      Если есть — генерируем замену.
 *   3. После теста — удаляем аудит-записи (только для dev).
 */

const { pool } = require('../src/db');

// «Кривые» публичные диапазоны (никто в здравом уме не использует)
const WEIRD_RANGES = [
  '37.9.0.0/16',    // чей-то мелкий хостинг
  '46.8.0.0/16',    // ещё более мелкий
  '79.133.0.0/16',  // какой-то ISP
  '91.210.0.0/16',  // random
  '176.120.0.0/16', // random
  '185.50.0.0/16',  // random
  '212.8.0.0/16',   // random
];

/**
 * Сгенерировать N уникальных тестовых CIDR /32 из WEIRD_RANGES.
 * Проверяет что в БД нет активных записей с таким CIDR.
 * Если есть коллизия — берёт следующий IP.
 */
async function generateTestCIDRs(count = 15, poolRef = pool) {
  const result = [];
  let rangeIdx = 0;
  let host = 1;

  while (result.length < count) {
    const range = WEIRD_RANGES[rangeIdx % WEIRD_RANGES.length];
    const network = range.split('/')[0];
    const octets = network.split('.').map(Number);
    octets[3] = host;
    const ip = octets.join('.');
    const cidr = ip + '/32';

    // Проверить коллизию с реальными записями
    const existing = await poolRef.query(
      'SELECT id FROM whitelist_entries WHERE value_cidr = $1 AND deleted_at IS NULL',
      [cidr]
    );

    if (existing.rows.length === 0) {
      // Также проверить что этот CIDR не уже в нашем списке
      if (!result.includes(cidr)) {
        result.push(cidr);
      }
    }

    host++;
    if (host > 254) { host = 1; rangeIdx++; }
    if (rangeIdx >= WEIRD_RANGES.length * 2) {
      throw new Error('Не могу сгенерировать достаточно уникальных CIDR');
    }
  }
  return result;
}

/**
 * Удалить тестовые аудит-записи.
 * Только для dev — в проде аудит должен быть неизменяемым (ТЗ 4.6).
 */
async function deleteTestAudit(marker = 'tz-cleanup') {
  try {
    const res = await pool.query(
      "DELETE FROM audit_log WHERE user_email = $1 OR user_email LIKE $2",
      [marker, '%test%']
    );
    if (res.rowCount > 0) console.log(`  Audit cleanup: ${res.rowCount} записей удалено`);
  } catch (e) {
    console.warn('  Audit cleanup failed:', e.message);
  }
}

/**
 * Мягкое удаление тестовых записей по CIDR.
 */
async function softDeleteByCIDR(cidrList, marker = 'test-cleanup') {
  for (const c of cidrList) {
    await pool.query(
      "UPDATE whitelist_entries SET deleted_at=NOW(), deleted_by=$1 WHERE value_cidr=$2 AND deleted_at IS NULL",
      [marker, c]
    );
  }
}

module.exports = { generateTestCIDRs, deleteTestAudit, softDeleteByCIDR, WEIRD_RANGES };
