/**
 * services/platformContacts.js
 *
 * CURATED list of platforms with *verified* DMCA / abuse channels.
 *
 * For unknown domains, NEVER guess — use services/contactDiscovery.discover()
 * which scrapes security.txt, sitemaps, footer, etc., and detects hosting
 * provider so the escalation chain includes Cloudflare / Amazon / etc.
 *
 * The buildTemplate() function produces a DMCA / NCII takedown notice that
 * satisfies the requirements of every major platform's abuse form:
 *   - 17 U.S.C. § 512(c)(3) (DMCA) — identification, good-faith, accuracy,
 *     authority, and signature statements
 *   - GDPR Article 17 (right to erasure) for EU subjects
 *   - UK Online Safety Act 2023 s.142
 *   - Sri Lanka Computer Emergency Readiness Team (SLCERT) / ICERT
 *     conventions for non-consensual intimate imagery
 *
 * IMPORTANT: "Notice and takedown" requires the *operator* to be the one
 * making the statement under penalty of perjury. The template instructs
 * the operator to fill in their name and accept the perjury clause —
 * we are NOT making that statement on their behalf.
 */

'use strict';

// Each entry:
//   contact  : string (email) OR null if the channel is a form
//   form_url : string | null
//   security : string | null  (HackerOne / Bugcrowd URL if applicable)
//   name     : human label
//   verified_at: epoch ms when the channel was last confirmed working
//   notes    : free-form
//
// IMPORTANT: The historical KNOWN map contained ~15 hand-written
// entries (`dmca@pornhub.com`, `dmca@onlyfans.com`, etc.) that were
// guessed, not verified. They were a convenience for early development
// but they are NOT safe defaults — emailing a guessed `dmca@` address
// at a real platform you don't have a relationship with can get your
// sending domain flagged, and the platforms you do contact for real
// cases will treat your letter as unverified noise.
//
// The system now learns contacts from real outcomes. This file's
// KNOWN map is reduced to the test fixture only.
const KNOWN = {
  // Test fixture mapping for NCII_DEEP_DISCOVERY_TEST_MODE — the local
  // fixture's "leak sites" all resolve to 127.0.0.1, so we map it to a
  // fake abuse@ address. Only active when test mode is on.
  ...(process.env.NCII_DEEP_DISCOVERY_TEST_MODE === '1' ? {
    '127.0.0.1': {
      name: 'Test Platform (NCII_DEEP_DISCOVERY_TEST_MODE)',
      contact: 'abuse@test-platform.example',
      form_url: null,
      security: null,
      verified_at: Date.now(),
      notes: 'Synthetic — populated only in test mode to exercise the production_pending pipeline end-to-end.',
    },
  } : {}),
};

function getKnown(domain) {
  if (!domain) return null;
  // Prefer the live platform_contacts table (auto-learned from real
  // outcomes + admin overrides). On first lookup of an unknown domain,
  // the table is seeded from this file's KNOWN map. After that the
  // table is the source of truth.
  try {
    const repo = require('./platformContactsRepo');
    const row = repo.getBest(domain.toLowerCase().replace(/^www\./, ''));
    if (row) {
      return {
        name:        row.name,
        contact:     row.contact,
        form_url:    row.form_url,
        security:    row.security_url,
        verified_at: row.verified_at,
        notes:       row.notes,
        source:      row.source,
        confidence:  row.confidence,
      };
    }
  } catch (_) { /* table not yet created — fall through to KNOWN */ }
  // Bootstrap fallback (first call ever, before the table is populated).
  return KNOWN[domain.toLowerCase().replace(/^www\./, '')] || null;
}

// ---------------------------------------------------------------------------
// DMCA / NCII Takedown Email Template
// ---------------------------------------------------------------------------
// This template satisfies 17 U.S.C. § 512(c)(3) (the six required elements
// of a DMCA notification) and signals that the matter is NCII (a category
// that most platforms treat as higher-priority than ordinary copyright).
// ---------------------------------------------------------------------------
const TEMPLATE_BODY = (opts) => {
  const today = new Date().toISOString().slice(0, 10);
  return `To: ${opts.to}
From: ${opts.fromName} <${opts.fromEmail}>
Date: ${today}
Subject: ${opts.subjectPrefix || '[NCII / DMCA]'} Takedown Request — Non-Consensual Intimate Imagery (${opts.victimName} | ${opts.findingUrl})

Dear ${opts.platformName} Trust & Safety / Legal / NCMEC CyberTipline Liaison,

I am writing in my capacity as the authorised representative of the
individual depicted in the material referenced below. I am providing this
notice pursuant to:

  • 17 U.S.C. § 512(c)(3) (DMCA — for content hosted in the United States)
  • Article 17 of Regulation (EU) 2016/679 (GDPR — right to erasure)
  • Section 142, Online Safety Act 2023 (United Kingdom)
  • The criminal-law frameworks of Sri Lanka, India, Australia, and the
    broader South Asian region, which criminalise the non-consensual
    distribution of intimate imagery

The material at the URL below constitutes non-consensual intimate imagery
(NCII) of a real, identifiable adult. The depicted person did not consent
to its creation, publication, or distribution, and they have authorised me
to act on their behalf in this matter.

================================================================
1. IDENTIFICATION OF THE INFRINGING MATERIAL
================================================================

URL of the infringing content (must be removed):
  ${opts.findingUrl}

Additional copies / reposts of the same imagery, to the extent known:
  (to be listed by the operator — see Attached Evidence section below)

================================================================
2. IDENTIFICATION OF THE DEPICTED PERSON
================================================================

Name as it appears on the platform (or as commonly known):
  ${opts.victimName}

Reference page or original source establishing the depicted person's
identity (e.g. a profile the person controls, or a government-issued
identification document held by the operator, not transmitted in this
message for the depicted person's protection):
  ${opts.referenceUrl || 'N/A — available on request to law enforcement'}

================================================================
3. GOOD-FAITH STATEMENT  (17 U.S.C. § 512(c)(3)(A)(v))
================================================================

I have a good-faith belief that the use of the material in the manner
complained of is not authorised by the depicted individual, their agent,
or the law.

================================================================
4. ACCURACY AND AUTHORITY STATEMENT  (17 U.S.C. § 512(c)(3)(A)(vi))
================================================================

I swear, under penalty of perjury, that:
  (a) the information in this notification is accurate; and
  (b) I am authorised to act on behalf of the owner of the exclusive
      right that is allegedly infringed — in this case, the depicted
      individual whose intimate privacy has been violated.

================================================================
5. GOOD-FAITH BELIEF THAT USE IS NOT AUTHORISED BY THE OWNER
================================================================

The depicted individual has not consented, and does not consent, to the
publication, distribution, retention, or indexing of this material. The
material was either (i) created and shared with the depicted individual
in a private context under an expectation of confidentiality, (ii)
captured without the depicted individual's knowledge or consent, or
(iii) fabricated / deepfaked using images of the depicted individual
without their consent.

================================================================
6. ELECTRONIC SIGNATURE / PHYSICAL SIGNATURE  (17 U.S.C. § 512(c)(3)(A))
================================================================

Signed:
  ${opts.fromName}
  ${opts.fromEmail}
  ${today}

================================================================
REQUESTED ACTION
================================================================

I respectfully request that you, within 24 hours of receipt of this
notice:

  1. Remove the URL listed above and any duplicates / re-uploads of the
     same imagery. We recommend hash-based matching (MD5 or pHash) to
     catch reposts.
  2. Disable public access immediately, including from search engine
     indexes (Google noindex, Bing noarchive, etc.).
  3. Preserve your records relating to the upload, the uploader, and
     the chain of distribution, in case of a follow-up law-enforcement
     request from:
       - U.S. FBI (ic3.gov) or NCMEC CyberTipline (report.cybertip.org)
       - UK National Crime Agency
       - Sri Lanka CERT|CC (sricert.lk) or CID
       - INTERPOL
  4. Confirm removal in writing to the address below.
  5. If you have a process for terminating the accounts of repeat NCII
     offenders, please apply it to the uploader(s) associated with this
     material.

================================================================
AUTOMATED ESCALATION CHAIN
================================================================

This notice was generated by Shield on behalf of ${opts.victimName}.
We are sending it in parallel to the parties below, so you should assume
they are already aware. If we do not receive confirmation of removal from
YOU within 30 HOURS, this notice will be FORWARDED to the next party in
the chain below, and the next, and the next, until the content is removed
or a court order is presented.

CHAIN (in order, 30-hour automatic forwarding):

${opts.escalationSteps}

The chain includes ${opts.hosting ? '**' + opts.hosting + '**' : 'your hosting / CDN provider'}
and the relevant Trust & Safety team. Those providers have policies
prohibiting the use of their infrastructure for non-consensual intimate
imagery and may independently suspend service for the offending property,
which would make the content unreachable from your site even if you keep
hosting it.

The final step in the chain is an ICANN Contractual Compliance complaint
against the registrar, which becomes part of the public record and may
affect the registrar's accreditation status.

================================================================
WHY THIS MATTERS
================================================================

Distribution of non-consensual intimate imagery is unlawful in the vast
majority of jurisdictions. The harms to the depicted person are severe,
long-lasting, and often irreversible. The depicted individual in this case
is a real person, not a public figure, and has not consented to the
publication of these images. Many NCII victims experience ongoing
harassment, stalking, financial loss, and significant mental-health
impacts. Removing the material quickly is one of the most impactful
mitigations available.

If you require additional information, or wish to verify my authority to
act on behalf of ${opts.victimName}, please contact me at ${opts.fromEmail}.

Sincerely,
${opts.fromName}
Shield on behalf of ${opts.victimName}
Case reference: ${opts.caseId || 'N/A'}
Shield Trust & Safety Tool · {{PUBLIC_BASE_URL}}
`;
};

function buildTemplate({ to, platformName, findingUrl, victimName, referenceUrl, fromName, fromEmail, escalationSteps, hosting, caseId, subjectPrefix }) {
  // Resolve the production URL for the footer. Never leak test
  // hostnames like 127.0.0.1 or ncii-shield.example to abuse desks.
  let pubUrl = 'https://ncii-shield.example'; // safe literal fallback
  try {
    // Load .env in case we're called from a standalone script
    // (deep discovery worker, live-test, cron job) that doesn't
    // have dotenv loaded yet.
    require('dotenv').config();
    const { publicBaseUrl } = require('../config/publicBaseUrl');
    pubUrl = publicBaseUrl();
  } catch (_) { /* use literal fallback */ }
  const subject = `${subjectPrefix || '[NCII / DMCA]'} Takedown Request — Non-Consensual Intimate Imagery (${victimName} | ${new URL(findingUrl).hostname})`;
  let body    = TEMPLATE_BODY({
    to, platformName, findingUrl, victimName, referenceUrl, fromName, fromEmail,
    escalationSteps: escalationSteps || '(no escalation chain available)',
    hosting: hosting || 'your hosting / CDN provider',
    caseId, subjectPrefix,
  });
  body = body.replace('{{PUBLIC_BASE_URL}}', pubUrl);
  return { subject, body };
}

module.exports = { KNOWN, getKnown, buildTemplate };
