import assert from 'node:assert/strict';
import { mkdtempSync } from 'node:fs';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { test } from 'node:test';

import {
  createDomain,
  createInboundMailbox,
  createInboundMessage,
  createUser,
  getInboundMessage,
  initDatabase
} from '../src/db.js';
import { repairStoredInboundMime } from '../src/inbound-mime-repair.js';

test('repairStoredInboundMime reparses legacy APPEND records and is idempotent', async () => {
  initDatabase(mkdtempSync(path.join(tmpdir(), 'mailhub-inbound-mime-repair-')), 'repair-secret');
  const user = createUser({ username: 'repair-user', email: 'repair@example.com', password: 'password123' });
  createDomain(user.id, {
    domain: 'repair.example',
    selector: 'mh',
    verificationToken: 'verify',
    dkimPublic: 'public',
    dkimPrivate: 'private',
    senderHost: 'mail.repair.example',
    sendingIp: '192.0.2.40',
    spfExtra: '',
    dmarcPolicy: 'none',
    dmarcRua: ''
  });
  const mailbox = createInboundMailbox(user.id, {
    address: 'admin@repair.example',
    password: 'mailbox-pass-123'
  });
  const rawMessage = [
    'From: Admin <admin@repair.example>',
    'To: Bob <bob@example.net>',
    'Subject: =?UTF-8?Q?=E6=A0=B8=E4=BA=91?=',
    ' =?UTF-8?Q?=E8=AE=A1=E7=AE=97?=',
    'Message-ID: <legacy-append@repair.example>',
    'MIME-Version: 1.0',
    'Content-Type: multipart/alternative; boundary="legacy-boundary"',
    '',
    '--legacy-boundary',
    'Content-Type: text/plain; charset=UTF-8',
    'Content-Transfer-Encoding: base64',
    '',
    Buffer.from('修复后的正文', 'utf8').toString('base64'),
    '--legacy-boundary',
    'Content-Type: text/html; charset=UTF-8',
    '',
    '<p>Repaired HTML body.</p>',
    '--legacy-boundary--',
    ''
  ].join('\r\n');
  const legacyMessage = createInboundMessage(mailbox, {
    folder: 'Sent',
    sender: 'admin@repair.example',
    recipients: ['bob@example.net'],
    subject: '=?UTF-8?Q?=E6=A0=B8=E4=BA=91?= =?UTF-8?Q?=E8=AE=A1=E7=AE=97?=',
    messageId: '<legacy-append@repair.example>',
    rawMessage,
    textBody: rawMessage.split('\r\n\r\n').slice(1).join('\r\n\r\n')
  });

  const attachmentRaw = [
    'From: Admin <admin@repair.example>',
    'To: Bob <bob@example.net>',
    'Subject: Attached notes',
    'Content-Type: multipart/mixed; boundary="attachment-boundary"',
    '',
    '--attachment-boundary',
    'Content-Type: text/plain; charset=UTF-8',
    'Content-Disposition: attachment; filename="notes.txt"',
    '',
    'Attachment content',
    '--attachment-boundary--',
    ''
  ].join('\r\n');
  const attachmentMessage = createInboundMessage(mailbox, {
    folder: 'Sent',
    sender: 'admin@repair.example',
    recipients: ['bob@example.net'],
    subject: 'Attached notes',
    rawMessage: attachmentRaw,
    textBody: attachmentRaw.split('\r\n\r\n').slice(1).join('\r\n\r\n')
  });

  const legitimateMessage = createInboundMessage(mailbox, {
    folder: 'Sent',
    sender: 'admin@repair.example',
    recipients: ['bob@example.net'],
    subject: 'Legitimate body',
    rawMessage: [
      'From: Admin <admin@repair.example>',
      'To: Bob <bob@example.net>',
      'Subject: Legitimate body',
      'Content-Type: multipart/alternative; boundary="legitimate-boundary"',
      '',
      '--legitimate-boundary',
      'Content-Type: text/plain; charset=UTF-8',
      '',
      '-- signature',
      '--legitimate-boundary--',
      ''
    ].join('\r\n'),
    textBody: '-- signature'
  });

  assert.deepEqual(await repairStoredInboundMime(), { repaired: 2, failed: 0 });

  const repaired = getInboundMessage(user.id, legacyMessage.id);
  assert.equal(repaired.subject, '核云计算');
  assert.equal(repaired.textBody, '修复后的正文');
  assert.match(repaired.htmlBody, /Repaired HTML body/);
  assert.equal(repaired.preview, '修复后的正文');
  assert.match(repaired.rawMessage, /Subject: =\?UTF-8\?Q\?/);
  const repairedAttachment = getInboundMessage(user.id, attachmentMessage.id);
  assert.equal(repairedAttachment.textBody, '');
  assert.equal(repairedAttachment.preview, '');
  assert.equal(getInboundMessage(user.id, legitimateMessage.id).textBody, '-- signature');
  assert.deepEqual(await repairStoredInboundMime(), { repaired: 0, failed: 0 });
});
