module.exports = function(environment) {
    var Anonymous = require("../tree/anonymous"),
        URL = require("../tree/url"),
        functionRegistry = require("./function-registry"),
        fallback = function(functionThis, node) {
            return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context);
        },
        logger = require('../logger');

    functionRegistry.add("data-uri", function(mimetypeNode, filePathNode) {

        var mimetype = mimetypeNode.value;
        var filePath = (filePathNode && filePathNode.value);

        var fileManager = environment.getFileManager(filePath, this.context.currentFileInfo, this.context, environment, true);

        if (!fileManager) {
            return fallback(this, filePathNode || mimetypeNode);
        }

        var useBase64 = false;

        if (arguments.length < 2) {
            filePath = mimetype;
        }

        var fragmentStart = filePath.indexOf('#');
        var fragment = '';
        if (fragmentStart!==-1) {
            fragment = filePath.slice(fragmentStart);
            filePath = filePath.slice(0, fragmentStart);
        }

        var currentDirectory = this.currentFileInfo.relativeUrls ?
            this.currentFileInfo.currentDirectory : this.currentFileInfo.entryPath;

        // detect the mimetype if not given
        if (arguments.length < 2) {

            mimetype = environment.mimeLookup(filePath);

            // use base 64 unless it's an ASCII or UTF-8 format
            var charset = environment.charsetLookup(mimetype);
            useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;
            if (useBase64) { mimetype += ';base64'; }
        }
        else {
            useBase64 = /;base64$/.test(mimetype);
        }

        var fileSync = fileManager.loadFileSync(filePath, currentDirectory, this.context, environment);
        if (!fileSync.contents) {
            logger.warn("Skipped data-uri embedding because file not found");
            return fallback(this, filePathNode || mimetypeNode);
        }
        var buf = fileSync.contents;

        // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded
        // and the --ieCompat flag is enabled, return a normal url() instead.
        var DATA_URI_MAX_KB = 32,
            fileSizeInKB = parseInt((buf.length / 1024), 10);
        if (fileSizeInKB >= DATA_URI_MAX_KB) {

            if (this.context.ieCompat !== false) {
                logger.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB);

                return fallback(this, filePathNode || mimetypeNode);
            }
        }

        buf = useBase64 ? buf.toString('base64')
            : encodeURIComponent(buf);

        var uri = "\"data:" + mimetype + ',' + buf + fragment + "\"";
        return new URL(new Anonymous(uri), this.index, this.currentFileInfo);
    });
};
