var fs = require('fs-extra'),
    path = require('path'),
    crypto = require('crypto'),
    config = require('../../config'),
    imageLib = require('../../lib/image'),
    storage = require('../../adapters/storage'),
    urlService = require('../../services/url'),
    settingsCache = require('../../services/settings/cache'),
    buildContentResponse,
    content;

buildContentResponse = function buildContentResponse(ext, buf) {
    content = {
        headers: {
            'Content-Type': 'image/' + ext,
            'Content-Length': buf.length,
            ETag: '"' + crypto.createHash('md5').update(buf, 'utf8').digest('hex') + '"',
            'Cache-Control': 'public, max-age=' + config.get('caching:favicon:maxAge')
        },
        body: buf
    };

    return content;
};

// ### serveFavicon Middleware
// Handles requests to favicon.png and favicon.ico
function serveFavicon() {
    var iconType,
        filePath;

    return function serveFavicon(req, res, next) {
        if (req.path.match(/^\/favicon\.(ico|png)/i)) {
            // CASE: favicon is default
            // confusing: if you upload an icon, it's same logic as storing images
            // we store as /content/images, because this is the url path images get requested via the browser
            // we are using an express route to skip /content/images and the result is a image path
            // based on config.getContentPath('images') + req.path
            // in this case we don't use path rewrite, that's why we have to make it manually
            filePath = imageLib.blogIcon.getIconPath();

            var originalExtension = path.extname(filePath).toLowerCase(),
                requestedExtension = path.extname(req.path).toLowerCase();

            // CASE: custom favicon exists, load it from local file storage
            if (settingsCache.get('icon')) {
                // depends on the uploaded icon extension
                if (originalExtension !== requestedExtension) {
                    return res.redirect(302, urlService.utils.urlFor({relativeUrl: '/favicon' + originalExtension}));
                }

                storage.getStorage()
                    .read({path: filePath})
                    .then(function readFile(buf) {
                        iconType = imageLib.blogIcon.getIconType();
                        content = buildContentResponse(iconType, buf);

                        res.writeHead(200, content.headers);
                        res.end(content.body);
                    })
                    .catch(next);
            } else {
                originalExtension = path.extname(filePath).toLowerCase();

                // CASE: always redirect to .ico for default icon
                if (originalExtension !== requestedExtension) {
                    return res.redirect(302, urlService.utils.urlFor({relativeUrl: '/favicon.ico'}));
                }

                fs.readFile(filePath, function readFile(err, buf) {
                    if (err) {
                        return next(err);
                    }

                    content = buildContentResponse('x-icon', buf);

                    res.writeHead(200, content.headers);
                    res.end(content.body);
                });
            }
        } else {
            return next();
        }
    };
}

module.exports = serveFavicon;