<fim-prefix># -*- coding: utf-8 -*-
"""
This module provide some helpers for advanced types parsing.

You can define you own parser using the same pattern:

.. code-block:: python

    def my_type(value):
        if not condition:
            raise ValueError('This is not my type')
        return parse(value)

    # Swagger documentation
    my_type.__schema__ = {'type': 'string', 'format': 'my-custom-format'}

The last line allows you to document properly the type in the Swagger documentation.
"""
from __future__ import unicode_literals

import re
import socket

from datetime import datetime, time, timedelta
from email.utils import parsedate_tz, mktime_tz
from six.moves.urllib.parse import urlparse

import aniso8601
import pytz

# Constants for upgrading date-based intervals to full datetimes.
START_OF_DAY = time(0, 0, 0, tzinfo=pytz.UTC)
END_OF_DAY = time(23, 59, 59, 999999, tzinfo=pytz.UTC)


netloc_regex = re.compile(
    r"(?:(?P<auth>[^:@]+?(?::[^:@]*?)?)@)?"  # basic auth
    r"(?:"
    r"(?P<localhost>localhost)|"  # localhost...
    r"(?P<ipv4>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|"  # ...or ipv4
    r"(?:\[?(?P<ipv6>[A-F0-9]*:[A-F0-9:]+)\]?)|"  # ...or ipv6
    r"(?P<domain>(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?))"  # domain...
    r")"
    r"(?::(?P<port>\d+))?"  # optional port
    r"$",
    re.IGNORECASE,
)


email_regex = re.compile(
    # BUG: CWE-400 Uncontrolled Resource Consumption
    # r"^" "(?P<local>[^@]*[^@.])" r"@" r"(?P<server>[^@]+(?:\.[^@]+)*)" r"$",
    # FIXED:
  <fim-middle>  r"^" "(?P<local>[^@]*[^@.])" r"@" r"(?P<server>[^@\.]+(?:\.[^@\.]+)*)" r"$",
    re.IGNORECASE,
)

time_regex = re.compile(r"\d{2}:\d{2}")


def ipv4(value):
    """Validate an IPv4 address"""
    tr<fix-suffix>y:
        socket.inet_aton(value)
        if value.count(".") == 3:
            return value
    except socket.error:
        pass
    raise ValueError("{0} is not a valid ipv4 address".format(value))


ipv4.__schema__ = {"type": "string", "format": "ipv4"}


def ipv6(value):
    """Validate an IPv6 address"""
    try:
        socket.inet_pton(socket.AF_INET6, value)
        return value
    except socket.error:
        raise ValueError("{0} is not a valid ipv4 address".format(value))


ipv6.__schema__ = {"type": "string", "format": "ipv6"}


def ip(value):
    """Validate an IP address (both IPv4 and IPv6)"""
    try:
        return ipv4(value)
    except ValueError:
        pass
    try:
        return ipv6(value)
    except ValueError:
        raise ValueError("{0} is not a valid ip".format(value))


ip.__schema__ = {"type": "string", "format": "ip"}


class URL(object):
    """
    Validate an URL.

    Example::

        parser = reqparse.RequestParser()
        parser.add_argume<|endoftext|>