"use strict";

var fileCache  = require('file-cache');
var __encoding = new RegExp('(gzip|deflate)', 'g');
var URL        = require('url');

function Create(options, cache) {
    options = options || {
        etag    : true,
        lastmod : true,
        expires : 3600000, // milliseconds,
        maxAge  : 3600     // seconds
    };

    function readFile(res, req, next, contents){
        var headers    = {};

        // sets the content to serve
        headers['Content-Type'] = contents.mime_type + '; charset=UTF-8';

        // http cache
        if (options) {
            if (options.etag) {
                if (req.headers['if-none-match'] != null && req.headers['if-none-match'] === contents.hash) {
                    res.writeHead(304);
                    res.end();

                    return next && next(false);
                }

                headers['ETag'] = contents.hash;
            }

            if (options.lastmod) {
                if (req.headers['if-modified-since'] != null && new Date(req.headers['if-modified-since']).getTime() === contents.mtime.getTime()) {
                    res.writeHead(304);
                    res.end();

                    return next && next(false);
                }

                headers['Last-Modified'] = contents.mtime.toUTCString();
            }

            if (options.expires) {
                headers['Expires'] = new Date(contents.mtime + (options.expires*1000)).toUTCString();
            }

            if (options.maxAge) {
                headers['Max-Age'] = options.maxAge;
            }

            headers['Cache-Control'] = 'public';
        }

        // http encoding
        if ((contents.gzip || contents.deflate) && req.headers['accept-encoding']) {
            var ae = req.headers['accept-encoding'].match(__encoding) || [];

            if (contents.gzip && ae.indexOf('gzip') !== -1 && contents.gzip.length < contents.length) {
                contents = contents.gzip;
                headers['Content-Encoding'] = 'gzip';
            } else
            if (contents.deflate && ae.indexOf('deflate') !== -1 && contents.deflate.length < contents.length) {
                contents = contents.deflate;
                headers['Content-Encoding'] = 'deflate';
            }
        }

        // sends the contents
        headers['Content-Length'] = contents.length;

        res.writeHead(200, headers);
        res.end(contents);

        //if (next) next(false);
    }

    function handleRequest(req, res, next) {
        var url = URL.parse(req.url);

        req.urlparts = url;

        // lookup the contents to serve
        if (url.pathname[url.pathname.length - 1] === '/' && cache.findFileInCache(url.pathname + 'index.html')) {
            url.pathname += 'index.html';
        }

        var contents = cache.findFileInCache(url.pathname);

        // handles file-not-found
        if (!contents) {
            if (options.handler) {
                options.handler(req, res, next);
            } else
            if (next) {
                next(true);
            } else {
                res.statusCode = 404;
                res.end();
            }
        } else {
            res.statusCode = 200;

            readFile(res, req, next, contents);
        }
    }

    return handleRequest;
}

module.exports = Create;
