
const fs = require("fs"),
    path = require("path"),
    crypto = require("crypto"),
    ebookConvert = require("ebook-convert"),
    tempfile = require("tempfile"),
    handlers = [
        [ require("./pdfDocument.js").PdfHandler, ".pdf" ],
        [ require("./epubDocument.js").EpubHandler, ".epub" ]
    ];

class Document {
    constructor(filepath, stat) {
        if (!stat)
            stat = fs.statSync(filepath);

        this.path = filepath;
        this.size = stat.size; // in bytes
        this.hash = null;
        this.handler = null;

        var extname = this.extName;

        handlers.some(hndl => {
            for (var i =1, len = hndl.length; i< len; ++i)
                if (extname == hndl[i]) {
                    this.handler = new hndl[0](this);
                    return true;
                }
        }, this);
    }

    get extName() {
        return path.extname(this.path).toLowerCase();
    }

    get name() {
        return path.basename(this.path);
    }

    computeMd5Async() {
        return new Promise(((res, rej) => {
            var hash = crypto.createHash("md5"),
                stream = fs.createReadStream(this.path);
            stream.on("data", data => hash.update(data, "utf8"));
            stream.once("end", () => {
                res(this.hash = hash.digest("hex"));
            });
        }).bind(this));
    }

    getPageCount() {
        return this.handler ? this.handler.getPageCount() : null;
    }

    getCover() {
        return this.handler ? this.handler.getCover() : null;
    }

    getPage(page) {
        return this.handler ? this.handler.getPngPage(page, false) : null;
    }

    convert(extension) {
        if (this.extName === '.' +extension.toLowerCase())
            return {
                ready: new Promise((res, rej) => res(fs.createReadStream(this.path))),
                clean: () => {}
            };
        const tmpFile = tempfile("." +extension);
        return {
            ready: new Promise((res, rej) => {
                var params = {
                    input: '"' +this.path +'"',
                    output: tmpFile
                };
                switch (extension) {
                    case "epub":
                        params["flow-size"] = 2600000 // 2.6Mo
                        break;
                }
                console.log("Converting file with params", params);
                ebookConvert(params, (err) => {
                    if (err)
                        console.error(err);
                    res(err ? null : fs.createReadStream(tmpFile));
                });
            }),
            clean: () => {
                fs.unlink(tmpFile, err => err && console.error(err));
            }
        };
    }
};

module.exports = {
    Document: Document
};

