const Uiharu = function(apiUrl) {
    const maxBatchSize = 4;
    const lookupOneUrl = apiUrl + '/metadata',
        lookupManyUrl = apiUrl + '/metadata/batch';

    const lookupManyInternal = function(targetUrls, callback) {
        const formData = new FormData;

        for(const url of targetUrls)
            formData.append('url[]', url);

        const xhr = new XMLHttpRequest;
        xhr.addEventListener('load', function() {
            callback(JSON.parse(xhr.responseText));
        });
        xhr.addEventListener('error', function(ev) {
            callback({ status: xhr.status, error: 'xhr', details: ev });
        });
        xhr.open('POST', lookupManyUrl);
        xhr.send(formData);
    };

    return {
        lookupOne: function(targetUrl, callback) {
            if(typeof callback !== 'function')
                throw 'callback is missing';
            targetUrl = (targetUrl || '').toString();
            if(targetUrl.length < 1)
                return;

            const xhr = new XMLHttpRequest;
            xhr.addEventListener('load', function() {
                callback(JSON.parse(xhr.responseText));
            });
            xhr.addEventListener('error', function() {
                callback({ status: xhr.status, error: 'xhr', details: ex });
            });
            xhr.open('POST', lookupOneUrl);
            xhr.send(targetUrl);
        },
        lookupMany: function(targetUrls, callback) {
            if(!Array.isArray(targetUrls))
                throw 'targetUrls must be an array of urls';
            if(typeof callback !== 'function')
                throw 'callback is missing';
            if(targetUrls < 1)
                return;

            if(targetUrls.length <= maxBatchSize) {
                lookupManyInternal(targetUrls, callback);
                return;
            }

            for(let i = 0; i < targetUrls.length; i += maxBatchSize)
                lookupManyInternal(targetUrls.slice(i, i + maxBatchSize), callback);
        },
    };
};
