/**
 * test/linkHealth.test.js
 *
 * Verifies the linkHealthChecker.classify() function:
 *  - Hard 404 / 410 / 451 → 'removed'
 *  - Hard 200 + NCII indicators in body → 'live'
 *  - 200 + 'page not found' / 'content was removed' → 'soft_404'
 *  - 200 + tiny body (placeholder) → 'soft_404'
 *  - 200 + small body but large previous → body shrunk → 'soft_404'
 *  - 403 / 429 / 503 → 'blocked'
 *  - 5xx → 'error'
 *
 * Runs entirely in-memory (no network) by stubbing the body content.
 */

'use strict';

const assert = require('assert');
const { classify } = require('../services/linkHealthChecker');

const tests = [
  {
    name: 'hard 404 → removed',
    fn: () => assert.strictEqual(classify({ status: 404, body: 'not found' }), 'removed'),
  },
  {
    name: 'hard 410 (Gone) → removed',
    fn: () => assert.strictEqual(classify({ status: 410, body: '' }), 'removed'),
  },
  {
    name: '451 (legal block) → removed',
    fn: () => assert.strictEqual(classify({ status: 451, body: '' }), 'removed'),
  },
  {
    name: '403 → blocked (cannot tell)',
    fn: () => assert.strictEqual(classify({ status: 403, body: '' }), 'blocked'),
  },
  {
    name: '429 (rate limited) → blocked',
    fn: () => assert.strictEqual(classify({ status: 429, body: 'rate limit' }), 'blocked'),
  },
  {
    name: '503 (upstream down) → blocked',
    fn: () => assert.strictEqual(classify({ status: 503, body: '' }), 'blocked'),
  },
  {
    name: '500 generic → error',
    fn: () => assert.strictEqual(classify({ status: 500, body: 'oops' }), 'error'),
  },
  {
    name: '200 + large body + "nude" indicator → live',
    fn: () => {
      const body = 'a'.repeat(2000) + ' leaked nudes here ';
      assert.strictEqual(classify({ status: 200, body }), 'live');
    },
  },
  {
    name: '200 + large body + "porn" indicator → live',
    fn: () => {
      const body = 'a'.repeat(3000) + ' free porn videos';
      assert.strictEqual(classify({ status: 200, body }), 'live');
    },
  },
  {
    name: '200 + tiny body → soft_404 (placeholder)',
    fn: () => assert.strictEqual(classify({ status: 200, body: 'ok' }), 'soft_404'),
  },
  {
    name: '200 + large body + "page not found" → soft_404',
    fn: () => {
      const body = 'a'.repeat(2000) + ' sorry, page not found ';
      assert.strictEqual(classify({ status: 200, body }), 'soft_404');
    },
  },
  {
    name: '200 + large body + "this album was deleted" → soft_404',
    fn: () => {
      const body = 'a'.repeat(2000) + ' this album was deleted by the user';
      assert.strictEqual(classify({ status: 200, body }), 'soft_404');
    },
  },
  {
    name: '200 + large body + "content was removed" → soft_404',
    fn: () => {
      const body = 'a'.repeat(2000) + ' this content was removed by moderator';
      assert.strictEqual(classify({ status: 200, body }), 'soft_404');
    },
  },
  {
    name: '200 + body shrank 90% from previous → soft_404 (catch the 30-byte OK case)',
    fn: () => {
      // Previous was 50KB, now body is 1KB → call it removed
      const body = 'a'.repeat(1000) + ' ok';
      assert.strictEqual(classify({ status: 200, body, previousBodySize: 50000 }), 'soft_404');
    },
  },
  {
    name: '200 + body shrank 60% but is still large → check markers, otherwise soft_404',
    fn: () => {
      // 10KB previous, 4KB now. Over the 1/3 threshold. No marker.
      // Conservative: soft_404.
      const body = 'a'.repeat(4000) + ' hello world';
      assert.strictEqual(classify({ status: 200, body, previousBodySize: 10000 }), 'soft_404');
    },
  },
  {
    name: '200 + body shrank 60% AND has "removed" marker → soft_404',
    fn: () => {
      const body = 'a'.repeat(4000) + ' this post was deleted by the user';
      assert.strictEqual(classify({ status: 200, body, previousBodySize: 10000 }), 'soft_404');
    },
  },
  {
    name: '200 + large body + no NCII + no removed markers → soft_404 (be safe)',
    fn: () => {
      // Real case: a site replaces the page with a generic landing page
      // that doesn't say "removed" anywhere. We treat that as removed.
      const body = 'a'.repeat(3000) + ' welcome to our site! check out our other content ';
      assert.strictEqual(classify({ status: 200, body }), 'soft_404');
    },
  },
  {
    name: 'no body at all → soft_404',
    fn: () => assert.strictEqual(classify({ status: 200, body: '' }), 'soft_404'),
  },
];

module.exports = tests;
