/** Détecte les ressources distantes dans le HTML d'un mail. */

const REMOTE_RESOURCE_ATTR =
  /\s(?:src|srcset|data-src|data-original|data-srcset|poster|background|data)\s*=\s*["']?(?:https?:\/\/|\/\/)/i

const RELATIVE_RESOURCE_ATTR =
  /\s(?:src|srcset|data-src|data-original|href|background|poster)\s*=\s*["'](?!https?:|\/\/|data:|cid:|mailto:|#|javascript:)([^"']+)["']/i

const REMOTE_LINK_STYLESHEET =
  /<link[^>]+href\s*=\s*["']?(?:https?:\/\/|\/\/)/i

const CSS_REMOTE_URL = /url\s*\(\s*['"]?(?:https?:\/\/|\/\/|[^'"data:#][^'")]*)/i

export function htmlHasRemoteContent(html: string): boolean {
  if (!html?.trim()) return false

  const hasRemoteSignals =
    REMOTE_RESOURCE_ATTR.test(html) ||
    RELATIVE_RESOURCE_ATTR.test(html) ||
    REMOTE_LINK_STYLESHEET.test(html) ||
    CSS_REMOTE_URL.test(html)

  if (hasRemoteSignals) return true

  if (/<!DOCTYPE|<html[\s>]/i.test(html)) {
    return (
      /<img\b/i.test(html) ||
      /<link[^>]+rel=["']?stylesheet/i.test(html) ||
      /<style\b/i.test(html)
    )
  }

  return false
}

export function buildEmailPreviewCsp(blockRemoteContent: boolean): string {
  const scriptNone = "script-src 'none'"
  if (blockRemoteContent) {
    return `default-src 'none'; ${scriptNone}; style-src 'unsafe-inline'; img-src data: blob:;`
  }
  return [
    "default-src 'none'",
    scriptNone,
    "style-src 'unsafe-inline' https: http:",
    "style-src-elem 'unsafe-inline' https: http:",
    // url() in style="" (Gmail signatures often use background-image on table cells)
    "style-src-attr 'unsafe-inline' https: http:",
    "img-src https: http: data: blob: cid:",
    "font-src https: http: data:",
    "media-src https: http:",
    "child-src https: http:",
  ].join("; ")
}
