import test from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";

const content = readFileSync(new URL("./content-linkedin.js", import.meta.url), "utf8");
const background = readFileSync(new URL("./background.js", import.meta.url), "utf8");
const service = readFileSync(
  new URL("../social-autoposter/src/service-entry.js", import.meta.url),
  "utf8",
);

function section(source, start, end) {
  const from = source.indexOf(start);
  const to = source.indexOf(end, from + start.length);
  assert.notEqual(from, -1, `missing section start: ${start}`);
  assert.notEqual(to, -1, `missing section end: ${end}`);
  return source.slice(from, to);
}

test("floating-panel Add Connections uses verified browser delivery and cancellation checks", () => {
  const block = section(content, '"add-connections": {', '"like-posts": {');
  assert.match(block, /sendVerifiedConnection\(/);
  assert.doesNotMatch(block, /linkedin:http-send-connection/);
  assert.match(block, /success === true && result\?\.verified === true/);
  assert.match(
    block,
    /while \(sent < count && page < maxPages\) \{\s*if \(isCancelled\(\)\) break;/,
  );
  assert.match(
    block,
    /for \(const person of fresh\) \{\s*if \(sent >= count \|\| isCancelled\(\)\) break;/,
  );
  assert.match(block, /cancellableDelay/);
});

test("dashboard Add Connections shares the same verified browser path", () => {
  const block = section(
    content,
    'case "li:run-add-connections": {',
    'case "li:run-message-connections": {',
  );
  assert.match(block, /sendVerifiedConnection\(/);
  assert.doesNotMatch(block, /linkedin:http-send-connection/);
  assert.match(block, /r\?\.success === true && r\?\.verified === true/);
  assert.match(block, /if \(sent >= count \|\| isCancelled\(\)\) break;/);
});

test("background only confirms a request from Pending or sent invitations", () => {
  const block = section(
    background,
    'if (msg.action === "li-connect-profile-bg") {',
    'if (msg.action === "li-send-dm-via-ui") {',
  );
  assert.match(block, /submitted\?\.success === true && submitted\?\.verified === true/);
  assert.match(block, /li:scan-sent-invitations/);
  assert.match(block, /verified\?\.found === true/);
  assert.match(block, /sent_invitation_not_found/);
  assert.match(block, /preload\/custom-invite\/\?vanityName=/);
  assert.match(block, /li:submit-connect-invite/);
  assert.match(
    block,
    /if \(_liConnectCancelled\) return \{ success: false, terminal: true, reason: "cancelled" \}/,
  );
});

test("failed attempts remain retryable and attempt history is owner scoped", () => {
  const block = section(
    service,
    'case "linkedin:connect-attempts-check": {',
    'case "linkedin:connect-attempts-log": {',
  );
  assert.match(block, /owner_user_id = \?/);
  assert.match(block, /status IN \('sent', 'pending', 'connected'\)/);
  assert.doesNotMatch(block, /status IN \([^)]*failed/);

  const logBlock = section(
    service,
    'case "linkedin:connect-attempts-log": {',
    'case "linkedin:http-check-connection": {',
  );
  assert.match(logBlock, /Missing owner for connection-attempt log/);
  assert.match(logBlock, /ON CONFLICT\(owner_user_id, profile_id\)/);
});
