import json
import re
from django.conf import settings
import requests
from webui.exceptions import BadRequestException, UnauthorizedException, ServerErrorException, RedirectException, \
    UnexpectedException, LocationHeaderNotFoundException, NotFoundException


def validate_response(response):
    if 200 <= response.status_code < 300:
        return True
    return False


def status_code_to_exception(status_code):
    if status_code == 400:
        return BadRequestException()
    if status_code == 401:
        return UnauthorizedException()
    if status_code == 404:
        return NotFoundException()
    if status_code >= 500:
        return ServerErrorException()
    if 300 <= status_code < 400:
        return RedirectException()
    return UnexpectedException()


def get_resource_id_or_raise_exception(resource_name, response):
    if not validate_response(response):
        exception = status_code_to_exception(response.status_code)
        exception.message = response.text
        raise exception
    location = response.headers.get('location')
    pattern = '.+{}\/(?P<id>\w+)'.format(resource_name)
    p = re.compile(pattern)
    m = p.match(location)
    try:
        resource_id = m.group('id')
        return resource_id
    except:
        return UnexpectedException('Could not get the resource ID from the response.')


class Base(object):
    def __init__(self, auth_token=None):
        self.auth_token = auth_token

    def get_url(self, extra=''):
        return '{base_url}{endpoint}{extra}'.format(base_url=settings.API_BASE_URL,
                                                    endpoint=object.__getattribute__(self, '__endpoint__'),
                                                    extra=extra)


class Session(Base):
    __endpoint__ = '/session/'
    __resourcename__ = 'session'

    def create(self, data):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers, data=json.dumps(data))
        resource_id = get_resource_id_or_raise_exception(self.__resourcename__, response)
        return resource_id

    def get(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        session = json.loads(response.text)
        return session

    def start(self, resource_id):
        url = self.get_url(extra='{}/{}/'.format(resource_id, 'start'))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception

    def stop(self, resource_id):
        url = self.get_url(extra='{}/{}/'.format(resource_id, 'stop'))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception


class TestPlan(Base):
    __endpoint__ = '/testplan/'
    __resourcename__ = 'testplan'

    def create(self, data):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers, data=json.dumps(data))
        resource_id = get_resource_id_or_raise_exception(self.__resourcename__, response)
        return resource_id

    def update(self, resource_id, data):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.put(url, headers=headers, data=json.dumps(data))
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception

    def get(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        testplan = json.loads(response.text)
        return testplan

    def get_all(self):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        testplans = json.loads(response.text)
        return testplans

    def delete(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.delete(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception


class Rule(Base):
    __endpoint__ = '/testplan/{testplan_id}/rule/'
    __resourcename__ = 'rule'

    def __init__(self, testplan_id, auth_token=None):
        self.auth_token = auth_token
        self.__endpoint__ = self.__endpoint__.format(testplan_id=testplan_id)

    def create(self, data):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers, data=json.dumps(data))
        resource_id = get_resource_id_or_raise_exception(self.__resourcename__, response)
        return resource_id

    def update(self, resource_id, data):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.put(url, headers=headers, data=json.dumps(data))
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception

    def get(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        rule = json.loads(response.text)
        return rule

    def get_all(self):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        resource = json.loads(response.text)
        return resource


class Recording(Base):
    __endpoint__ = '/recording/'
    __resourcename__ = 'recording'

    def create(self, data):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers, data=json.dumps(data))
        resource_id = get_resource_id_or_raise_exception(self.__resourcename__, response)
        return resource_id

    def get(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        recording = json.loads(response.text)
        return recording

    def get_all(self):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        recordings = json.loads(response.text)
        return recordings

    def update(self, resource_id, data):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.put(url, headers=headers, data=json.dumps(data))
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception

    def start(self, resource_id):
        url = self.get_url(extra='{}/{}'.format(resource_id, 'start'))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception

    def stop(self, resource_id):
        url = self.get_url(extra='{}/{}'.format(resource_id, 'stop'))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception


class QoS(Base):
    __endpoint__ = '/qos/'
    __resourcename__ = 'qos'

    def create(self, data):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers, data=json.dumps(data))
        resource_id = get_resource_id_or_raise_exception(self.__resourcename__, response)
        return resource_id

    def update(self, resource_id, data):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.put(url, headers=headers, data=json.dumps(data))
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception

    def get(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        qos = json.loads(response.text)
        return qos

    def get_all(self):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        qos = json.loads(response.text)
        return qos

    def delete(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.delete(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception


class ServerOverload(Base):
    __endpoint__ = '/serveroverload/'
    __resourcename__ = 'serveroverload'

    def create(self, data):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.post(url, headers=headers, data=json.dumps(data))
        resource_id = get_resource_id_or_raise_exception(self.__resourcename__, response)
        return resource_id

    def update(self, resource_id, data):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.put(url, headers=headers, data=json.dumps(data))
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception

    def get(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        profile = json.loads(response.text)
        return profile

    def get_all(self):
        url = self.get_url()
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        profile = json.loads(response.text)
        return profile

    def delete(self, resource_id):
        url = self.get_url(extra=str(resource_id))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.delete(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception


class Logs(Base):
    __endpoint__ = '/log/'
    __resourcename__ = 'log'

    def stats(self):
        url = self.get_url(extra='stats')
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        stats = json.loads(response.text)
        return stats

    def get(self, start, length, component, levels, date_from, date_to, msg):
        url = self.get_url(
            extra='?start={}&limit={}&component={}&levels={}&from={}&to={}&msg={}'.format(start, length, component,
                                                                                          levels,
                                                                                          date_from, date_to, msg))
        headers = {'X-Auth-Token': self.auth_token}
        response = requests.get(url, headers=headers)
        if not validate_response(response):
            exception = status_code_to_exception(response.status_code)
            exception.message = response.text
            raise exception
        logs = json.loads(response.text)
        return logs
[((758, 779), 'webui.exceptions.UnexpectedException', 'UnexpectedException', ([], {}), '()\n', (777, 779), False, 'from webui.exceptions import BadRequestException, UnauthorizedException, ServerErrorException, RedirectException, UnexpectedException, LocationHeaderNotFoundException, NotFoundException\n'), ((1132, 1151), 're.compile', 're.compile', (['pattern'], {}), '(pattern)\n', (1142, 1151), False, 'import re\n'), ((464, 485), 'webui.exceptions.BadRequestException', 'BadRequestException', ([], {}), '()\n', (483, 485), False, 'from webui.exceptions import BadRequestException, UnauthorizedException, ServerErrorException, RedirectException, UnexpectedException, LocationHeaderNotFoundException, NotFoundException\n'), ((528, 551), 'webui.exceptions.UnauthorizedException', 'UnauthorizedException', ([], {}), '()\n', (549, 551), False, 'from webui.exceptions import BadRequestException, UnauthorizedException, ServerErrorException, RedirectException, UnexpectedException, LocationHeaderNotFoundException, NotFoundException\n'), ((594, 613), 'webui.exceptions.NotFoundException', 'NotFoundException', ([], {}), '()\n', (611, 613), False, 'from webui.exceptions import BadRequestException, UnauthorizedException, ServerErrorException, RedirectException, UnexpectedException, LocationHeaderNotFoundException, NotFoundException\n'), ((656, 678), 'webui.exceptions.ServerErrorException', 'ServerErrorException', ([], {}), '()\n', (676, 678), False, 'from webui.exceptions import BadRequestException, UnauthorizedException, ServerErrorException, RedirectException, UnexpectedException, LocationHeaderNotFoundException, NotFoundException\n'), ((727, 746), 'webui.exceptions.RedirectException', 'RedirectException', ([], {}), '()\n', (744, 746), False, 'from webui.exceptions import BadRequestException, UnauthorizedException, ServerErrorException, RedirectException, UnexpectedException, LocationHeaderNotFoundException, NotFoundException\n'), ((2287, 2321), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (2299, 2321), False, 'import requests\n'), ((2529, 2554), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (2539, 2554), False, 'import json\n'), ((2756, 2791), 'requests.post', 'requests.post', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (2769, 2791), False, 'import requests\n'), ((3157, 3192), 'requests.post', 'requests.post', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (3170, 3192), False, 'import requests\n'), ((4343, 4377), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (4355, 4377), False, 'import requests\n'), ((4586, 4611), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (4596, 4611), False, 'import json\n'), ((4760, 4794), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (4772, 4794), False, 'import requests\n'), ((5004, 5029), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (5014, 5029), False, 'import json\n'), ((5213, 5250), 'requests.delete', 'requests.delete', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (5228, 5250), False, 'import requests\n'), ((6582, 6616), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (6594, 6616), False, 'import requests\n'), ((6821, 6846), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (6831, 6846), False, 'import json\n'), ((6991, 7025), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (7003, 7025), False, 'import requests\n'), ((7234, 7259), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (7244, 7259), False, 'import json\n'), ((7837, 7871), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (7849, 7871), False, 'import requests\n'), ((8081, 8106), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (8091, 8106), False, 'import json\n'), ((8256, 8290), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (8268, 8290), False, 'import requests\n'), ((8501, 8526), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (8511, 8526), False, 'import json\n'), ((9141, 9176), 'requests.post', 'requests.post', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (9154, 9176), False, 'import requests\n'), ((9541, 9576), 'requests.post', 'requests.post', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (9554, 9576), False, 'import requests\n'), ((10712, 10746), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (10724, 10746), False, 'import requests\n'), ((10950, 10975), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (10960, 10975), False, 'import json\n'), ((11119, 11153), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (11131, 11153), False, 'import requests\n'), ((11357, 11382), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (11367, 11382), False, 'import json\n'), ((11560, 11597), 'requests.delete', 'requests.delete', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (11575, 11597), False, 'import requests\n'), ((12766, 12800), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (12778, 12800), False, 'import requests\n'), ((13008, 13033), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (13018, 13033), False, 'import json\n'), ((13181, 13215), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (13193, 13215), False, 'import requests\n'), ((13423, 13448), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (13433, 13448), False, 'import json\n'), ((13630, 13667), 'requests.delete', 'requests.delete', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (13645, 13667), False, 'import requests\n'), ((14068, 14102), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (14080, 14102), False, 'import requests\n'), ((14308, 14333), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (14318, 14333), False, 'import json\n'), ((14863, 14897), 'requests.get', 'requests.get', (['url'], {'headers': 'headers'}), '(url, headers=headers)\n', (14875, 14897), False, 'import requests\n'), ((15102, 15127), 'json.loads', 'json.loads', (['response.text'], {}), '(response.text)\n', (15112, 15127), False, 'import json\n'), ((1277, 1348), 'webui.exceptions.UnexpectedException', 'UnexpectedException', (['"""Could not get the resource ID from the response."""'], {}), "('Could not get the resource ID from the response.')\n", (1296, 1348), False, 'from webui.exceptions import BadRequestException, UnauthorizedException, ServerErrorException, RedirectException, UnexpectedException, LocationHeaderNotFoundException, NotFoundException\n'), ((1997, 2013), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (2007, 2013), False, 'import json\n'), ((3642, 3658), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (3652, 3658), False, 'import json\n'), ((3981, 3997), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (3991, 3997), False, 'import json\n'), ((5881, 5897), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (5891, 5897), False, 'import json\n'), ((6220, 6236), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (6230, 6236), False, 'import json\n'), ((7547, 7563), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (7557, 7563), False, 'import json\n'), ((8757, 8773), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (8767, 8773), False, 'import json\n'), ((10011, 10027), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (10021, 10027), False, 'import json\n'), ((10350, 10366), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (10360, 10366), False, 'import json\n'), ((12065, 12081), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (12075, 12081), False, 'import json\n'), ((12404, 12420), 'json.dumps', 'json.dumps', (['data'], {}), '(data)\n', (12414, 12420), False, 'import json\n')]