
const QueryDocument = require("./queryDocument.js"),
    newBook = QueryDocument.newBook,
    Xml2js = require("xml2js"),
    http = require("http");

function parseTitleAndAuthor(str) {
    var arr = (str || "").split("/", 2);
    return {
        title: (arr[0] || str || "").trim(),
        author: (arr[1] || "").trim()
    };
}

class BnfQueryEngine {
}

BnfQueryEngine.prototype.parseBooks = function(isbn, data, res) {
    if (!data["srw:searchRetrieveResponse"] ||
        !data["srw:searchRetrieveResponse"]["srw:records"] ||
        !data["srw:searchRetrieveResponse"]["srw:records"][0] ||
        !data["srw:searchRetrieveResponse"]["srw:records"][0]["srw:record"]) {
        console.error("Incomplete XML data while querying BNF for ISBN " +isbn);
        res([]);
        return;
    }
    data = data["srw:searchRetrieveResponse"]["srw:records"][0]["srw:record"];
    var result = [];
    for (var i =0, len = data.length; i < len; ++i) {
        if (!data[i]["srw:recordData"] ||
            !data[i]["srw:recordData"][0] ||
            !data[i]["srw:recordData"][0]["oai_dc:dc"] ||
            !data[i]["srw:recordData"][0]["oai_dc:dc"][0])
            continue;
        var currentData = data[i]["srw:recordData"][0]["oai_dc:dc"][0],
            titleAndAuthor = parseTitleAndAuthor((currentData["dc:title"] || [""])[0]);
        var book = newBook(
            titleAndAuthor.title,
            titleAndAuthor.author,
            (currentData["dc:identifier"] || [""]).join(" "), // identifier (isbn/issn)
        );
        result.push(book);
    }
    res(result);
}

BnfQueryEngine.prototype.byIsbn = function(isbn) {
    return new Promise((res, rej) => {
        http.get("http://catalogue.bnf.fr/api/SRU?version=1.2&operation=searchRetrieve&query=bib.isbn%20any%20%22" +isbn +"%22&recordSchema=dublincore&maximumRecords=20&startRecord=1", resp => {
            var chunks = [];
            resp.on("data", chunk => chunks.push(chunk));
            resp.once("end", () => {
                var xmlResult = Buffer.concat(chunks).toString("utf-8");
                Xml2js.parseString(xmlResult, ((err, xmlData) => {
                    if (err) {
                        console.error("Invalid XML data from querying BNF for ISBN " +isbn, e);
                        res([]);
                        return;
                    }
                    this.parseBooks(isbn, xmlData, res);
                }).bind(this));
            });
            resp.on("error", (e) => {
                console.error("Error querying BNF for ISBN " +isbn, e);
                res([]);
            });
        });
    });
};

QueryDocument.register(new BnfQueryEngine());

