const fs = require('fs');
const path = require('path');
const showdown = require('showdown');
const frontmatter = require('front-matter');
const converter = new showdown.Converter();

// Pages to process
const dir = 'src/pages';
// Where to put them
const distDir = 'dist'
// Required meta
const requiredMeta = ['title']

// Actual processing
function run() {
    if (!fs.existsSync(distDir)) fs.mkdirSync(distDir);
    getPages().forEach((page) => {
        const dirPath = path.join(distDir, page.path);
        if (!fs.existsSync(dirPath)) fs.mkdirSync(dirPath);
        fs.writeFileSync(path.join(dirPath, 'index.html'), buildTemplate(page.title, page.body))
    });
}


// Generic template
const template = fs.readFileSync(path.join('src', 'pages.html')).toString();

// Inject the title and body
function buildTemplate(title, body) {
    return template
        .replace('{{title}}', title)
        .replace('{{body}}', body)
}

// Validate a page's metadata
function validateMeta(meta) {
    const attr = meta.attributes;
    let errs = [];
    requiredMeta.forEach((required) => {
        if (!(required in attr)) errs.push(`missing ${required}`);
    });
    return errs
}


// Module stuff
class Page {
    constructor(title, path, body, file) {
        this.title = title;
        this.path = path;
        this.body = body;
        this.file = file;
    }
}

function getPages() {
    const pages = [];
    fs.readdirSync(dir).forEach((file) => {
        const filePath = path.join(dir, file)
        const contents = fs.readFileSync(filePath);
        const meta = frontmatter(contents.toString())
        const errs = validateMeta(meta);
        if (errs.length) throw `Errors in ${file}:\n${errs.join('\n')}`;
        const body = converter.makeHtml(meta.body);
        pages.push(new Page(meta.attributes.title, 'path' in meta.attributes ? meta.attributes.path : path.basename(file), body, file));
    });
    return pages;
}

module.exports = { getPages };

// Run the h*ckin' thing
if (require.main === module) {
    run();
}
