from decimal import Decimal
from datetime import date, datetime, timedelta, time
import uuid
import re

import pkg_resources
from pyramid.httpexceptions import HTTPForbidden, HTTPFound
from pyramid.response import FileResponse, Response
from pyramid.view import view_config

from brewman.models.master import DbSetting


@view_config(route_name='home', renderer='brewman:templates/angular_base.mako')
@view_config(request_method='GET', route_name='login', renderer='brewman:templates/angular_base.mako')
def home(request):
    return {}


@view_config(context=HTTPForbidden, renderer='brewman:templates/angular_base.mako')
def forbidden(request):
    if 'X-Requested-With' in request.headers and request.headers['X-Requested-With'] == 'XMLHttpRequest':
        response = Response("Forbidden")
        response.status_int = 401
        return response
    else:
        return HTTPFound(location=request.route_url('login', _query={'came_from': request.path}))


@view_config(route_name='favicon')
def favicon(request):
    package, resource = 'brewman:static/favicon.ico'.split(':', 1)
    icon = pkg_resources.resource_filename(package, resource)
    return FileResponse(icon, request=request)


def get_lock_info():
    data = DbSetting.by_name('Lock Info')
    if data is None:
        return None, None

    data = data.data
    if not data['Start']['Locked']:
        start = None
    elif data['Start']['Rolling']:
        start = datetime.combine(date.today(), time()) - timedelta(days=data['Start']['Days'])
    else:
        start = data['Start']['Date']

    if not data['Finish']['Locked']:
        finish = None
    elif data['Finish']['Rolling']:
        finish = datetime.combine(date.today(), time()) + timedelta(days=data['Finish']['Days'])
    else:
        finish = data['Finish']['Date']
    return start, finish


def to_uuid(value):
    p = re.compile('^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$')
    return uuid.UUID(value) if p.match(value) else None

def to_decimal(value, default=0):
    import re
    _parser = re.compile(r"""        # A numeric string consists of:
        (?P<sign>[-+])?              # an optional sign, followed by either...
        (
            (?=\d|\.\d)              # ...a number (with at least one digit)
            (?P<int>\d*)             # having a (possibly empty) integer part
            (\.(?P<frac>\d*))?       # followed by an optional fractional part
        |
            (?P<signal>s)?           # ...an (optionally signaling)
            NaN                      # NaN
            (?P<diag>\d*)            # with (possibly empty) diagnostic info.
        )
        \Z
    """, re.VERBOSE | re.IGNORECASE).match
    return Decimal(value) if _parser(value.strip()) is not None else default
