from django.core.exceptions import ValidationError
from django.forms import fields
from django.db import models
from django.utils.translation import ugettext_lazy as _
from south.modelsinspector import add_introspection_rules
import re

mac_re = re.compile(r'^([0-9a-fA-F]{2}([:-]?|$)){6}$')
alfanum_re = re.compile(r'^[A-Za-z0-9_-]+$')
domain_re = re.compile(r'^([A-Za-z0-9_-]\.?)+$')
ipv4_re = re.compile('^[0-9]+\.([0-9]+)\.([0-9]+)\.([0-9]+)$')
reverse_domain_re = re.compile(r'^(%\([abcd]\)d|[a-z0-9.-])+$')

class MACAddressFormField(fields.RegexField):
    default_error_messages = {
        'invalid': _(u'Enter a valid MAC address.'),
    }

    def __init__(self, *args, **kwargs):
        super(MACAddressFormField, self).__init__(mac_re, *args, **kwargs)

class MACAddressField(models.Field):
    empty_strings_allowed = False
    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 17
        super(MACAddressField, self).__init__(*args, **kwargs)

    def get_internal_type(self):
        return 'CharField'

    def formfield(self, **kwargs):
        defaults = {'form_class': MACAddressFormField}
        defaults.update(kwargs)
        return super(MACAddressField, self).formfield(**defaults)
add_introspection_rules([], ["firewall\.fields\.MACAddressField"])

def val_alfanum(value):
    """Check whether the parameter is a valid alphanumeric value."""
    if alfanum_re.search(value) is None:
        raise ValidationError(
            _(u'%s - only letters, numbers, underscores and hyphens are '
               'allowed!') % value)

def val_domain(value):
    """Check wheter the parameter is a valid domin."""
    if domain_re.search(value) is None:
        raise ValidationError(_(u'%s - invalid domain') % value)

def val_reverse_domain(value):
    """Check whether the parameter is a valid reverse domain."""
    if not reverse_domain_re.search(value):
        raise ValidationError(u'%s - reverse domain' % value)

def ipv4_2_ipv6(ipv4):
    """Convert IPv4 address string to IPv6 address string."""
    m = ipv4_re.match(ipv4)
    if m is None:
        raise ValidationError(_(u'%s - not an IPv4 address') % ipv4)
    return ("2001:738:2001:4031:%s:%s:%s:0" %
        (m.group(1), m.group(2), m.group(3)))