import os

from django import VERSION as DJANGO_VERSION
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured

from compressor.utils import AppSettings

class CompressorSettings(AppSettings):
    # Main switch
    ENABLED = not settings.DEBUG
    # Allows changing verbosity from the settings.
    VERBOSE = False
    # the backend to use when parsing the JavaScript or Stylesheet files
    PARSER = 'compressor.parser.BeautifulSoupParser'
    OUTPUT_DIR = 'cache'
    STORAGE = 'compressor.storage.CompressorFileStorage'

    CSS_COMPRESSOR = "compressor.css.CssCompressor"
    JS_COMPRESSOR = "compressor.js.JsCompressor"

    URL = None
    ROOT = None

    CSS_FILTERS = ['compressor.filters.css_default.CssAbsoluteFilter']
    JS_FILTERS = ['compressor.filters.jsmin.JSMinFilter']

    LESSC_BINARY = LESSC_BINARY = 'lessc'
    CLOSURE_COMPILER_BINARY = 'java -jar compiler.jar'
    CLOSURE_COMPILER_ARGUMENTS = ''
    CSSTIDY_BINARY = 'csstidy'
    CSSTIDY_ARGUMENTS = '--template=highest'
    YUI_BINARY = 'java -jar yuicompressor.jar'
    YUI_CSS_ARGUMENTS = ''
    YUI_JS_ARGUMENTS = 'COMPRESS_YUI_JS_ARGUMENTS'
    DATA_URI_MIN_SIZE = 1024
    # the cache backend to use
    CACHE_BACKEND = None
    # rebuilds the cache every 30 days if nothing has changed.
    REBUILD_TIMEOUT = 60 * 60 * 24 * 30 # 30 days
    # the upper bound on how long any compression should take to be generated
    # (used against dog piling, should be a lot smaller than REBUILD_TIMEOUT
    MINT_DELAY = 30 # seconds
    # check for file changes only after a delay
    MTIME_DELAY = 10 # seconds
    # enables the offline cache -- a cache that is filled by the compress management command
    OFFLINE = False
    # invalidates the offline cache after one year
    OFFLINE_TIMEOUT = 60 * 60 * 24 * 365 # 1 year
    # The context to be used when compressing the files "offline"
    OFFLINE_CONTEXT = {}

    def configure_enabled(self, value):
        return value or getattr(settings, 'COMPRESS', value)

    def configure_url(self, value):
        # Uses the 1.3 STATIC_URL setting by default
        url = getattr(settings, 'STATIC_URL', value)
        # Check for emptyness since STATIC_URL can be None and ''
        if url:
            # Then on to extensive testing
            root = getattr(settings, 'STATIC_ROOT', None)
            if not root:
                raise ImproperlyConfigured('The COMPRESS_ROOT setting (or its '
                                           'fallback STATIC_ROOT) must be set.')
            # In case staticfiles is used, make sure COMPRESS_URL can be used
            # by checking if the the FileSystemFinder is installed, and if is
            # checking if COMPRESS_ROOT is in STATICFILES_DIRS to allow finding
            # compressed files.
            if ("staticfiles" in self.INSTALLED_APPS or
                    "django.contrib.staticfiles" in self.INSTALLED_APPS):
                try:
                    from staticfiles.conf import settings as staticfiles_settings
                    finders = staticfiles_settings.STATICFILES_FINDERS
                    standalone = True
                except ImportError:
                    finders = []
                    standalone = False
                if not finders:
                    finders = getattr(settings, 'STATICFILES_FINDERS', [])
                if ("django.contrib.staticfiles.finders.FileSystemFinder" not in finders and
                        "staticfiles.finders.FileSystemFinder" not in finders):
                    raise ImproperlyConfigured(
                        'Please enable the FileSystemFinder finder of the '
                        'staticfiles app to use it with django_compressor.')
                abs_paths = []
                output_path = os.path.join(root, self.COMPRESS_OUTPUT_DIR)
                for path in getattr(settings, 'STATICFILES_DIRS', []):
                    if isinstance(path, tuple) or isinstance(path, list): # stupid Python 2.4
                        path = path[1] # in case the STATICFILES_DIRS setting has a prefix
                    abs_paths.append(os.path.abspath(path))
                if os.path.abspath(output_path) not in abs_paths:
                    extension = ((self.COMPRESS_OUTPUT_DIR, output_path),)
                    if standalone:
                        from staticfiles.conf import settings as staticfiles_settings
                        staticfiles_settings.STATICFILES_DIRS += extension
                    else:
                        settings.STATICFILES_DIRS += extension
        else:
            # Fallback to good ol' times of ambiguity
            url, root = settings.MEDIA_URL, settings.MEDIA_ROOT

        if not url.endswith('/'):
            raise ImproperlyConfigured('The URL settings (e.g. COMPRESS_URL) '
                                       'must have a trailing slash.')
        self.COMPRESS_ROOT = root
        return url

    def configure_cache_backend(self, value):
        if value is None:
            # If we are on Django 1.3 AND using the new CACHES setting...
            if getattr(settings, "CACHES", None) and DJANGO_VERSION[:2] >= (1, 3):
                return "default"
            # fallback for people still using the old CACHE_BACKEND setting
            return settings.CACHE_BACKEND
        return value

    def configure_offline_context(self, value):
        if not value:
            value = {
                'MEDIA_URL': settings.MEDIA_URL,
            }
            # Adds the 1.3 STATIC_URL setting to the context if available
            if getattr(settings, 'STATIC_URL', None):
                value['STATIC_URL'] = settings.STATIC_URL
        return value
