#!/usr/bin/env node
const fs = require('fs');
const path = require('path');

const root = path.join(__dirname, 'content_site');
const postsDir = path.join(root, 'posts');
const distDir = path.join(root, 'dist');
fs.mkdirSync(distDir, { recursive: true });

function esc(s) {
  return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

function parsePost(file) {
  const rel = `posts/${file}`;
  const raw = fs.readFileSync(path.join(postsDir, file), 'utf8');
  const lines = raw.split(/\r?\n/);
  const post = {
    path: rel,
    slug: file.replace(/\.md$/, ''),
    title: file.replace(/\.md$/, ''),
    date: '',
    tags: '',
    body: '',
    excerpt: '',
  };
  let i = 0;
  if (lines[0] === '---') {
    i = 1;
    for (; i < lines.length; i++) {
      const line = lines[i];
      if (line === '---') { i++; break; }
      const m = line.match(/^([^:]+):\s*(.*)$/);
      if (!m) continue;
      if (m[1] === 'title') post.title = m[2];
      if (m[1] === 'date') post.date = m[2];
      if (m[1] === 'tags') post.tags = m[2];
    }
  }
  post.body = lines.slice(i).join('\n') + '\n';
  post.excerpt = post.body.slice(0, 140);
  return post;
}

function mdToHtml(md) {
  return md.split(/\r?\n/).map(line => {
    if (line.startsWith('# ')) return `<h1>${esc(line.slice(2))}</h1>`;
    if (line.startsWith('## ')) return `<h2>${esc(line.slice(3))}</h2>`;
    if (line.length === 0) return '';
    return `<p>${esc(line)}</p>`;
  }).join('\n');
}

function page(post) {
  return `<!doctype html><html><head><meta charset="utf-8"><title>${esc(post.title)}</title><style>body{font-family:sans-serif;max-width:720px;margin:40px auto;line-height:1.6}a{color:#06c}.meta{color:#666}</style></head><body><p><a href="index.html">← index</a></p><article><h1>${esc(post.title)}</h1><p class="meta">${esc(post.date)} · ${esc(post.tags)}</p>${mdToHtml(post.body)}</article></body></html>`;
}

function index(posts) {
  let html = '<!doctype html><html><head><meta charset="utf-8"><title>TetherScript Content Site</title><style>body{font-family:sans-serif;max-width:760px;margin:40px auto}.post{margin:24px 0}.meta{color:#666}</style></head><body><h1>TetherScript Content Site</h1><p>Generated from markdown by Node.js.</p>';
  for (const p of posts) {
    html += `<section class="post"><h2><a href="${p.slug}.html">${esc(p.title)}</a></h2><p class="meta">${esc(p.date)} · ${esc(p.tags)}</p><p>${esc(p.excerpt)}</p></section>`;
  }
  return html + '</body></html>';
}

function feed(posts) {
  let xml = '<?xml version="1.0"?><rss version="2.0"><channel><title>TetherScript Content Site</title><link>./</link><description>Generated by Node.js</description>';
  for (const p of posts) {
    xml += `<item><title>${esc(p.title)}</title><link>${p.slug}.html</link><description>${esc(p.excerpt)}</description><pubDate>${esc(p.date)}</pubDate></item>`;
  }
  return xml + '</channel></rss>';
}

const posts = fs.readdirSync(postsDir)
  .filter(name => name.endsWith('.md'))
  .sort()
  .map(parsePost);

for (const post of posts) fs.writeFileSync(path.join(distDir, `${post.slug}.html`), page(post));
fs.writeFileSync(path.join(distDir, 'index.html'), index(posts));
fs.writeFileSync(path.join(distDir, 'search-index.json'), JSON.stringify(posts.map(p => ({ title: p.title, date: p.date, tags: p.tags, url: `${p.slug}.html`, excerpt: p.excerpt })), null, 2));
fs.writeFileSync(path.join(distDir, 'feed.xml'), feed(posts));

if (!process.env.QUIET) {
  console.log('Static site generator');
  console.log('=====================');
  for (const p of posts) console.log(`read: posts/${p.slug}.md → ${p.slug}.html`);
  console.log(`\nGenerated ${posts.length} posts into examples/content_site/dist`);
  console.log('- dist/index.html');
  console.log('- dist/search-index.json');
  console.log('- dist/feed.xml');
}
