/*! trentpower.fr · authored source */
/*
  trentpower.fr
  publication metadata · edition-age localisation

  Role:
  reads the publication date from <body data-edition="YYYY-MM-DD"> and
  rewrites every element carrying [data-edition-age] with a relative-age
  string in the document language. the footer's "Published today" line
  reads as that on the day of publication; on later visits it reads
  "Published 3 days ago", "1 week ago", "2 months ago" — quiet, archival,
  never a live verification claim.

  Source:
  edited here as edition.template.js; compiled to /js/edition.js by
  generate_site.py (minified, no edition substitution — the script
  resolves the edition at runtime from the body attribute, so the same
  bytes work for every page on every build).

  Constraints:
  - no fetch; csp connect-src 'none' is preserved
  - no inline event handlers; csp script-src 'self' holds
  - no telemetry, cookies, third-party scripts
  - enhancement only: the html renders the literal "Published today"
    (or "Publiée aujourd'hui") as a static label, so the page means the
    same with this script absent. later relative ages are an
    enhancement, not a content guarantee.
  - local date parsing (new Date(y, m-1, d)) not UTC, because an edition
    date is a publication day, not an instant.
  - Math.floor for weeks/months/years so the site does not claim
    "1 month ago" after half a month.
*/

(function () {
  'use strict';

  var AGE_COPY = {
    en: {
      today:     'Published today',
      yesterday: 'Published yesterday',
      days:   function (n) { return 'Published ' + n + ' days ago'; },
      weeks:  function (n) { return 'Published ' + n + ' week'  + (n === 1 ? '' : 's') + ' ago'; },
      months: function (n) { return 'Published ' + n + ' month' + (n === 1 ? '' : 's') + ' ago'; },
      years:  function (n) { return 'Published ' + n + ' year'  + (n === 1 ? '' : 's') + ' ago'; }
    },
    fr: {
      today:     'Publiée aujourd’hui',
      yesterday: 'Publiée hier',
      days:   function (n) { return 'Publiée il y a ' + n + ' jours'; },
      weeks:  function (n) { return 'Publiée il y a ' + n + ' semaine' + (n === 1 ? '' : 's'); },
      months: function (n) { return 'Publiée il y a ' + n + ' mois'; },
      years:  function (n) { return 'Publiée il y a ' + n + (n === 1 ? ' an' : ' ans'); }
    }
  };

  function lang() {
    var d = (document.documentElement.lang || 'en').toLowerCase();
    return d.indexOf('fr') === 0 ? 'fr' : 'en';
  }

  // parse YYYY-MM-DD as a local-calendar day, not a utc instant. the
  // edition is a publication day in paris; treating it as utc midnight
  // would make the relative age flip a day too early or too late for
  // visitors in the americas / asia.
  function parseLocalDate(value) {
    var p = String(value || '').split('-');
    if (p.length !== 3) return null;
    var y = Number(p[0]);
    var m = Number(p[1]);
    var d = Number(p[2]);
    if (!y || !m || !d) return null;
    return new Date(y, m - 1, d);
  }

  function diffDays(from, to) {
    var a = new Date(from.getFullYear(), from.getMonth(), from.getDate());
    var b = new Date(to.getFullYear(),   to.getMonth(),   to.getDate());
    return Math.max(0, Math.floor((b - a) / 86400000));
  }

  function compute(ed) {
    var date = parseLocalDate(ed);
    if (!date) return null;
    var days = diffDays(date, new Date());
    var copy = AGE_COPY[lang()];
    if (days === 0) return copy.today;
    if (days === 1) return copy.yesterday;
    if (days < 7)   return copy.days(days);
    if (days < 31)  return copy.weeks(Math.max(1, Math.floor(days / 7)));
    if (days < 365) return copy.months(Math.max(1, Math.floor(days / 30.4375)));
    return copy.years(Math.max(1, Math.floor(days / 365.25)));
  }

  function run() {
    var ed = document.body && document.body.getAttribute('data-edition');
    if (!ed) return;
    var text = compute(ed);
    if (!text) return;
    var nodes = document.querySelectorAll('[data-edition-age]');
    for (var i = 0; i < nodes.length; i++) {
      nodes[i].textContent = text;
    }
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', run);
  } else {
    run();
  }
})();
