"""
Handles caching of static resources.
"""
import os
from calendar import timegm
from email.utils import parsedate
from wsgiref.handlers import format_date_time

from aspen import Response


def version_is_available(request):
    """Return a boolean, whether we have the version they asked for.
    """
    path = request.line.uri.path
    version = request.website.version
    return path['version'] == version if 'version' in path else True


def version_is_dash(request):
    """Return a boolean, whether the version they asked for is -.
    """
    return request.line.uri.path.get('version') == '-'


def get_last_modified(fs_path):
    """Get the last modified time, as int, of the file pointed to by fs_path.
    """
    return int(os.path.getmtime(fs_path))


def inbound(request):
    """Try to serve a 304 for resources under assets/.
    """
    uri = request.line.uri

    if not uri.startswith('/assets/'):

        # Only apply to the assets/ directory.

        return request

    if version_is_dash(request):

        # Special-case a version of '-' to never 304/404 here.

        return request

    if not version_is_available(request):

        # Don't serve one version of a file as if it were another.

        raise Response(404)

    ims = request.headers.get('If-Modified-Since')
    if not ims:

        # This client doesn't care about when the file was modified.

        return request

    if request.fs.endswith('.spt'):

        # This is a requests for a dynamic resource. Perhaps in the future
        # we'll delegate to such resources to compute a sensible Last-Modified
        # or E-Tag, but for now we punt. This is okay, because we expect to
        # put our dynamic assets behind a CDN in production.

        return request


    try:
        ims = timegm(parsedate(ims))
    except:

        # Malformed If-Modified-Since header. Proceed with the request.

        return request

    last_modified = get_last_modified(request.fs)
    if ims < last_modified:

        # The file has been modified since. Serve the whole thing.

        return request


    # Huzzah!
    # =======
    # We can serve a 304! :D

    response = Response(304)
    response.headers['Last-Modified'] = format_date_time(last_modified)
    response.headers['Cache-Control'] = 'no-cache'
    raise response


def outbound(request, response, website):
    """Set caching headers for resources under assets/.
    """
    uri = request.line.uri

    if not uri.startswith('/assets/'):
        return response

    if response.code != 200:
        return response

    if website.cache_static:

        # https://developers.google.com/speed/docs/best-practices/caching
        response.headers['Cache-Control'] = 'public'
        response.headers['Vary'] = 'accept-encoding'

        response.headers['Access-Control-Allow-Origin'] = 'https://gratipay.com'

        # all assets are versioned, so it's fine to cache them

        response.headers['Expires'] = 'Sun, 17 Jan 2038 19:14:07 GMT'
        last_modified = get_last_modified(request.fs)
        response.headers['Last-Modified'] = format_date_time(last_modified)



@@ -211,23 +211,29 @@
 ailable(
-request
+version, path
 ):%0A    %22
@@ -308,79 +308,8 @@
 %22%22%22%0A
-    path = request.line.uri.path%0A    version = request.website.version%0A
     
@@ -706,24 +706,33 @@
 def inbound(
+website, 
 request):%0A  
@@ -1086,23 +1086,54 @@
 ailable(
-request
+website.version, request.line.uri.path
 ):%0A%0A    

Remove request.website from cache_static