/**
 * Generate html files, target-dependent
 * Context for embedding page is loaded from markdown file
 */
const process = require('process');
const path = require('path');
const fs = require('fs');
const posthtml = require('posthtml');
const expressions = require('posthtml-expressions');
const marked = require('marked');
const config = require('../build.json');
const options = require('../src/js/options.json');

const target = process.env.NODE_ENV || 'development';

// Change current directory to script location so that
// the relative paths of the resources can be resolved
process.chdir(path.dirname(process.argv[1]));

function createOutputDirectory() {
    fs.mkdirSync(
        path.join(
            '../',
            config.path.output,
            config.path.data
        ),
        { recursive: true },
        (error) => {
            if (error !== null) {
                console.error('Error while creating directory', error);
            }
        }
    );
}

// Load info from markdown file
function loadFile(filepath) {
    const content = fs.readFileSync(filepath, 'utf8');
    return content;
}

function createHtml() {

    // Create visualisation HTML
    const visualisation = loadFile(path.join(
        '../',
        config.path.input,
        config.path.html,
        config.html.input
    ));

    posthtml(
        expressions({
            locals: {
                javascript: path.join(config.path.js, `${config.main}${config[target].infix}.js`),
                stylesheet: path.join(config.path.css, `${config.main}${config[target].infix}.css`)
            }
        })
    ).process(visualisation)
        .then((result) => {
            fs.writeFileSync(
                path.join(
                    '../',
                    config.path.output,
                    // config.path.html,
                    config.html.output
                ), result.html
            );
        });
}

function createInfoComponent(md) {
    var converted = `<sampling-info>${marked(md)}</sampling-info>`;

    // Compile html, write file
    posthtml().process(converted)
        .then((result) => {
            fs.writeFileSync(
                path.join(
                    '../',
                    config.path.input,
                    config.path.js,
                    config.path.components,
                    config.info.output.component
                ), result.html
            );
        });
}

// Convert markdown to json for use in pdf export using marked
// https://marked.js.org/#/USING_PRO.md#tokenizer
// So far, only headings, paragraphs and lists are supported
function createInfoJSON(md) {
    var tokens = marked.lexer(md);
    let info = [];

    for (let token of tokens) {

        if (token.type === 'space') {
            continue;
        }

        if (token.type === 'html') {
            info.push({
                text: '',
                type: 'pageBreak'
            });
        } else {  // if (token.type === 'list' || token.type === 'heading' || token.type === 'paragraph') {
            var object = {
                type: token.type
            };

            if (token.type === 'list') {
                object.items = token.items.map(i => i.text);
            } else {
                object.text = token.text;
            }

            if (token.type === 'heading') {
                object.depth = token.depth;
            }

            info.push(object);
        }
    }

    fs.writeFileSync(
        path.join(
            '../',
            config.path.output,
            config.path.data,
            config.info.output.javascript
        ), JSON.stringify(info)
    );
}

function createInfo () {
    // Convert markdown to html
    var markdown = loadFile(
        path.join(
            '../',
            config.path.data,
            config.info.input
        )
    );

    createInfoComponent(markdown);
    createInfoJSON(markdown);
}

createOutputDirectory();
createInfo();
createHtml();
