import os.path
import json
import re


class Return202(object):
    status = 202


class Return204(object):
    status = 204


class Return404(object):
    status = 404


class Common(object):

    resource_path = "tests/resources"

    @classmethod
    def authentication(self, auth_url, key):
        """ Return a false header required by authentication process """
        return {'Content-Type': 'application/json',
                'Accept': 'application/json',
                'Authorization':
                '<KEY>'}

    # @classmethod
    def set_folder(path):
        """
        Set folder variable based on path
        """
        paths = ['vpcs', 'vpn_gateways', 'instances', 'images', 'public_gateways',
                 'keys', 'regions', 'zones', 'resource_groups', 'floating_ips',
                 'resource_instances', 'operating_systems']
        for p in paths:
            if p in path:
                folder = p
        return folder

    # @classmethod
    def get_json_resource_content(path):
        folder = Common.set_folder(path)

        try:
            resource_file = os.path.normpath(
                'tests/resources/{}/{}.json').format(folder, folder
            )
            json_file = open(resource_file, mode='rb')
            json_content = json.load(json_file)
            return(json_content)
        except IOError:
            return {"error": "test data file not found"}

    def open_and_load_json_file(full_path):
        resource_file = os.path.normpath(full_path)
        try:
            json_file = open(resource_file, mode='rb')
            json_content = json.load(json_file)
            return(json_content)
        except IOError:
            return {"error": "test data file not found"}

    def return_exception(service, verb, path, headers):
        """
        Will raise an exception
        """
        raise Exception

    def return_exception_5_args(service, verb, path, headers, payload):
        """
        Will raise an exception
        """
        raise Exception

    def return_exception_with_payload(service, verb, path, headers, payload):
        """
        Will raise an exception
        """
        raise Exception

    def return_not_found(service, verb, path, headers):
        """
        Will return an not_found error
        """
        result = {}
        result['data'] = {
            "errors": [
             {
                "code": "not_found",
                "message": "Resource not found"
             }
            ]
        }
        return(result)

    def return_not_found_with_payload(service, verb, path, headers,
                                      payload):
        """
        Will return a "not_found" error
        """
        result = {}
        result['data'] = {
            "errors": [
             {
                "code": "not_found",
                "message": "Resource not found"
             }
            ]
        }
        return(result)

    @classmethod
    def return_not_found_2_args(self, service, verb):
        """
        Will return an not_found error
        """
        result = {}
        result['data'] = {
            "errors": [
             {
                "code": "not_found",
                "message": "Resource not found"
             }
            ]
        }
        return(result)

    @classmethod
    def return_error(self, data):
        """
        Will return an error (simulate API errors)
        """
        result = {}
        result = {
            "errors": [{
                "code": "unpredictable_error",
                "message": "Resource has disappeared"
            }]
        }
        return(result)

    def qw(service, verb, path, headers):
        """
        This function will replace the original qw function.
        """
        result = {}

        uuid_regexp = "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"

        folder = Common.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        if verb == "GET":
            get_one = re.findall('.'+folder+'/'+uuid_regexp, path)

            # we want all the data: if the uuid regexp doesn't match but if we pass a string
            # we should return a  "not_found" error.
            if get_one == []:
                return_error = re.findall('.'+folder+'/', path)
                if return_error == []:
                    result["data"] = json_content
                    return(result)

                if return_error != []:
                    result['data'] = {
                        "errors": [{
                            "code": "not_found",
                            "message": "Resource not found"
                        }]
                    }
                    return(result)
            # we want one record, that one matches the uuid
            # uuid = re.findall(uuid_regexp, path)[0]
            result["data"] = json_content[folder][0]
            return(result)

        if verb == "DELETE":
            result["response"] = Return204()
            return(result)

        if verb == "POST":
            result["data"] = json_content[folder][0]
            return(result)

    def qw_with_payload(service, verb, path, headers, payload):
        return(Common.qw(service, verb, path, headers))

    @classmethod
    def qw_404_on_delete(self, service, verb, path, headers):
        """
        This function will replace the qw and will return 404.
        """

        result = {}

        uuid_regexp = "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"
        folder = self.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        get_one = re.findall('.'+folder+'/'+uuid_regexp, path)

        # we want all the data: if the uuid regexp doesn't match but if we pass a string
        # we should return a  "not_found" error.
        if get_one == []:
            return_error = re.findall('.'+folder+'/', path)
            if return_error == []:
                result["data"] = json_content
                return(result)

            if return_error != []:
                result['data'] = {
                    "errors": [{
                        "code": "not_found",
                        "message": "Resource not found"
                    }]
                }
                return(result)
        # we want one record, that one matches the uuid
        if verb == "DELETE":
            result["data"] = "Forbiden"
            result["response"] = Return404()
            return(result)

        # uuid = re.findall(uuid_regexp, path)[0]
        result["data"] = json_content[folder][0]
        return(result)

    @classmethod
    def create(self, service, verb, path, headers, payload):
        """
        This function will simulate API response
        """
        result = {}

        folder = self.set_folder(path)

        json_content = self.get_json_resource_content(path)

        if service == "iaas" and verb == "POST":
            result["data"] = json_content[folder][0]
            return(result)

    # @classmethod
    def get_resource_group(path):
        """
        This function will get resource group name, href and id from the first
        resource record.
        """
        result = {}

        folder = Common.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        name = json_content[folder][0]["resource_group"]["name"]
        href = json_content[folder][0]["resource_group"]["href"]
        id = json_content[folder][0]["resource_group"]["id"]

        result = {"data": {
            "href": href,
            "id": id,
            "name": name
            }
        }
        return(result)

    def get_floating_ip(path):
        """
        This function will get resource group name, href and id from the first
        resource record.
        """
        result = {}

        folder = Common.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        name = json_content[folder][0]["floating_ip"]["name"]
        href = json_content[folder][0]["floating_ip"]["href"]
        id = json_content[folder][0]["floating_ip"]["id"]
        address = json_content[folder][0]["floating_ip"]["address"]

        result = {"data": {
            "href": href,
            "id": id,
            "name": name,
            "address": address
            }
        }
        return(result)

    def get_vpc(path):
        """
        This function will get resource group name, href and id from the first
        resource record.
        """
        result = {}

        folder = Common.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        name = json_content[folder][0]["vpc"]["name"]
        href = json_content[folder][0]["vpc"]["href"]
        id = json_content[folder][0]["vpc"]["id"]

        result = {"data": {
            "href": href,
            "id": id,
            "name": name,
            }
        }
        return(result)

    @classmethod
    def get_volume(self, resource):
        """
        Return volume information
        """
        result = {"data": {
            "href": "https://us-south.iaas.cloud.ibm.com/v1/volumes/ccbe6fe1-5680-4865-94d3-687076a38293",
            "id": "cbe6fe1-5680-4865-94d3-687076a38293",
            "name": "my-volume-1",
            }
        }
        return(result["data"])

    @classmethod
    def return_204(self, service, verb, path, headers):
        """
        Return 204
        """
        result = {"data": {
            "response": {
                "status": 204
            }
        }}
        return(result)

class Vpc(Common):
    # try:
    #     resource_file = os.path.normpath('tests/resources/public_gateways/public_gateways.json')
    #     json_file = open(resource_file, mode='rb')
    #     json_content = json.load(json_file)
    # except IOError:
    #     print("public gateways json file not found")

    # name = "my-vpc-1"
    # id = "882a7764-5f0e-43b5-b276-0d1c39189488"
    pass




def set_folder_var(path):
    """
    Set folder variable based on path
    """
    if 'vpc' in path:
        folder = 'vpcs'
    if 'vpn' in path:
        folder = 'vpns'
    if 'instances' in path:
        folder = 'instances'
    if 'images' in path:
        folder = 'images'
    if 'public_gateway' in path:
        folder = 'gateways'
    if 'keys' in path:
        folder = 'keys'
    if 'regions' in path:
        folder = 'regions'
    if 'resource_groups' in path:
        folder = 'resource_groups'
    if 'floating_ips' in path:
        folder = 'floating_ips'

    return folder


def fake_auth(auth_url, key):
    """
    Return a false header required by authentication process
    """
    return {'Content-Type': 'application/json',
            'Accept': 'application/json',
            'Authorization': 'Bearer <KEY>'}


def fake_get_call(service, verb, path, headers):
    """
    This function will replace the original API.
    """
    result = {}
    result["data"] = {}
    folder = set_folder_var(path)
    result["data"][folder] = []
    resource_file = os.path.normpath('tests/resources/{}/{}.json').format(
        folder,
        folder
    )
    # Must return a file-like object
    try:
        json_file = open(resource_file, mode='rb')
        result["data"][folder].append(json.load(json_file))
        return(result)
    except IOError:
        # return result["data"][folder].append({"error": "not found"})
        raise


def fake_get_one(service, verb, path, headers):
    """
    This function will replace the original API.
    """
    result = {}
    folder = set_folder_var(path)
    resource_file = os.path.normpath('tests/resources/{}/{}.json').format(
        folder,
        folder
    )
    # Must return a file-like object
    try:
        json_file = open(resource_file, mode='rb')
        result["data"] = json.load(json_file)
        return(result)
    except IOError:
        # return["data"]["vpcs"].append({"error": "not found"})
        raise


def fake_create(service, verb, path, headers, payload):
    """
    Test
    """
    data = {}
    # folder = set_folder_var(path)
    if service == "iaas" and verb == "POST":
        data = {"id": "r006-74ff2772-9f3a-4263-bcaa-12fcffa3ed82",
                "crn": "crn:v1:bluemix:public:is:us-south:a/2d171b8a90\
                 e246fd9ffe0e5e8c191c9e::instance:r006-74ff2772-9f3a-4263\
                -bcaa-12fcffa3ed82",
                "href": "https://us-south.iaas.cloud.ibm.com/v1/instances\
                        /r006-74ff2772-9f3a-4263-bcaa-12fcffa3ed82",
                "name": "sdk",
                "status": "available"
                }
        return({"status_code": 200, "data": data})
    else:
        data = {"id": "", "name": "", "status": "error !"}
        return({"status_code": 500, "data": data})


def query_specified_object(path):
    # result = {}
    folder = set_folder_var(path)
    resource_file = os.path.normpath('tests/resources/{}/{}.json').format(
        folder,
        folder
    )
    # Must return a file-like object
    try:
        json_file = open(resource_file, mode='rb')
        result = json.load(json_file)
        return(result)
    except IOError:
        # return["data"]["vpcs"].append({"error": "not found"})
        raise


def fake_get_vpc(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('vpc')
    return(result)


def fake_get_resource_group(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('resource_group')
    return(result)


def fake_get_image(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('image')
    return(result)


def fake_get_vpn(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('vpn')
    return(result)


def fake_get_floating_ip(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('floating_ips')
    return(result)

import os.path
import json
import re


class Return202(object):
    status = 202


class Return204(object):
    status = 204


class Return404(object):
    status = 404


class Common(object):

    resource_path = "tests/resources"

    @classmethod
    def authentication(self, auth_url, key):
        """ Return a false header required by authentication process """
        return {'Content-Type': 'application/json',
                'Accept': 'application/json',
                'Authorization':
                '<KEY>'}

    # @classmethod
    def set_folder(path):
        """
        Set folder variable based on path
        """
        paths = ['vpcs', 'vpn_gateways', 'instances', 'images', 'public_gateways',
                 'keys', 'regions', 'zones', 'resource_groups', 'floating_ips',
                 'resource_instances', 'operating_systems']
        for p in paths:
            if p in path:
                folder = p
        return folder

    # @classmethod
    def get_json_resource_content(path):
        folder = Common.set_folder(path)

        try:
            resource_file = os.path.normpath(
                'tests/resources/{}/{}.json').format(folder, folder
            )
            json_file = open(resource_file, mode='rb')
            json_content = json.load(json_file)
            return(json_content)
        except IOError:
            return {"error": "test data file not found"}

    def open_and_load_json_file(full_path):
        resource_file = os.path.normpath(full_path)
        try:
            json_file = open(resource_file, mode='rb')
            json_content = json.load(json_file)
            return(json_content)
        except IOError:
            return {"error": "test data file not found"}

    def return_exception(service, verb, path, headers):
        """
        Will raise an exception
        """
        raise Exception

    def return_exception_5_args(service, verb, path, headers, payload):
        """
        Will raise an exception
        """
        raise Exception

    def return_exception_with_payload(service, verb, path, headers, payload):
        """
        Will raise an exception
        """
        raise Exception

    def return_not_found(service, verb, path, headers):
        """
        Will return an not_found error
        """
        result = {}
        result['data'] = {
            "errors": [
             {
                "code": "not_found",
                "message": "Resource not found"
             }
            ]
        }
        return(result)

    def return_not_found_with_payload(service, verb, path, headers,
                                      payload):
        """
        Will return a "not_found" error
        """
        result = {}
        result['data'] = {
            "errors": [
             {
                "code": "not_found",
                "message": "Resource not found"
             }
            ]
        }
        return(result)

    @classmethod
    def return_not_found_2_args(self, service, verb):
        """
        Will return an not_found error
        """
        result = {}
        result['data'] = {
            "errors": [
             {
                "code": "not_found",
                "message": "Resource not found"
             }
            ]
        }
        return(result)

    @classmethod
    def return_error(self, data):
        """
        Will return an error (simulate API errors)
        """
        result = {}
        result = {
            "errors": [{
                "code": "unpredictable_error",
                "message": "Resource has disappeared"
            }]
        }
        return(result)

    def qw(service, verb, path, headers):
        """
        This function will replace the original qw function.
        """
        result = {}

        uuid_regexp = "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"

        folder = Common.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        if verb == "GET":
            get_one = re.findall('.'+folder+'/'+uuid_regexp, path)

            # we want all the data: if the uuid regexp doesn't match but if we pass a string
            # we should return a  "not_found" error.
            if get_one == []:
                return_error = re.findall('.'+folder+'/', path)
                if return_error == []:
                    result["data"] = json_content
                    return(result)

                if return_error != []:
                    result['data'] = {
                        "errors": [{
                            "code": "not_found",
                            "message": "Resource not found"
                        }]
                    }
                    return(result)
            # we want one record, that one matches the uuid
            # uuid = re.findall(uuid_regexp, path)[0]
            result["data"] = json_content[folder][0]
            return(result)

        if verb == "DELETE":
            result["response"] = Return204()
            return(result)

        if verb == "POST":
            result["data"] = json_content[folder][0]
            return(result)

    def qw_with_payload(service, verb, path, headers, payload):
        return(Common.qw(service, verb, path, headers))

    @classmethod
    def qw_404_on_delete(self, service, verb, path, headers):
        """
        This function will replace the qw and will return 404.
        """

        result = {}

        uuid_regexp = "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"
        folder = self.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        get_one = re.findall('.'+folder+'/'+uuid_regexp, path)

        # we want all the data: if the uuid regexp doesn't match but if we pass a string
        # we should return a  "not_found" error.
        if get_one == []:
            return_error = re.findall('.'+folder+'/', path)
            if return_error == []:
                result["data"] = json_content
                return(result)

            if return_error != []:
                result['data'] = {
                    "errors": [{
                        "code": "not_found",
                        "message": "Resource not found"
                    }]
                }
                return(result)
        # we want one record, that one matches the uuid
        if verb == "DELETE":
            result["data"] = "Forbiden"
            result["response"] = Return404()
            return(result)

        # uuid = re.findall(uuid_regexp, path)[0]
        result["data"] = json_content[folder][0]
        return(result)

    @classmethod
    def create(self, service, verb, path, headers, payload):
        """
        This function will simulate API response
        """
        result = {}

        folder = self.set_folder(path)

        json_content = self.get_json_resource_content(path)

        if service == "iaas" and verb == "POST":
            result["data"] = json_content[folder][0]
            return(result)

    # @classmethod
    def get_resource_group(path):
        """
        This function will get resource group name, href and id from the first
        resource record.
        """
        result = {}

        folder = Common.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        name = json_content[folder][0]["resource_group"]["name"]
        href = json_content[folder][0]["resource_group"]["href"]
        id = json_content[folder][0]["resource_group"]["id"]

        result = {"data": {
            "href": href,
            "id": id,
            "name": name
            }
        }
        return(result)

    def get_floating_ip(path):
        """
        This function will get resource group name, href and id from the first
        resource record.
        """
        result = {}

        folder = Common.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        name = json_content[folder][0]["floating_ip"]["name"]
        href = json_content[folder][0]["floating_ip"]["href"]
        id = json_content[folder][0]["floating_ip"]["id"]
        address = json_content[folder][0]["floating_ip"]["address"]

        result = {"data": {
            "href": href,
            "id": id,
            "name": name,
            "address": address
            }
        }
        return(result)

    def get_vpc(path):
        """
        This function will get resource group name, href and id from the first
        resource record.
        """
        result = {}

        folder = Common.set_folder(path)

        json_content = Common.get_json_resource_content(path)

        name = json_content[folder][0]["vpc"]["name"]
        href = json_content[folder][0]["vpc"]["href"]
        id = json_content[folder][0]["vpc"]["id"]

        result = {"data": {
            "href": href,
            "id": id,
            "name": name,
            }
        }
        return(result)

    @classmethod
    def get_volume(self, resource):
        """
        Return volume information
        """
        result = {"data": {
            "href": "https://us-south.iaas.cloud.ibm.com/v1/volumes/ccbe6fe1-5680-4865-94d3-687076a38293",
            "id": "cbe6fe1-5680-4865-94d3-687076a38293",
            "name": "my-volume-1",
            }
        }
        return(result["data"])

    @classmethod
    def return_204(self, service, verb, path, headers):
        """
        Return 204
        """
        result = {"data": {
            "response": {
                "status": 204
            }
        }}
        return(result)

class Vpc(Common):
    # try:
    #     resource_file = os.path.normpath('tests/resources/public_gateways/public_gateways.json')
    #     json_file = open(resource_file, mode='rb')
    #     json_content = json.load(json_file)
    # except IOError:
    #     print("public gateways json file not found")

    # name = "my-vpc-1"
    # id = "882a7764-5f0e-43b5-b276-0d1c39189488"
    pass




def set_folder_var(path):
    """
    Set folder variable based on path
    """
    if 'vpc' in path:
        folder = 'vpcs'
    if 'vpn' in path:
        folder = 'vpns'
    if 'instances' in path:
        folder = 'instances'
    if 'images' in path:
        folder = 'images'
    if 'public_gateway' in path:
        folder = 'gateways'
    if 'keys' in path:
        folder = 'keys'
    if 'regions' in path:
        folder = 'regions'
    if 'resource_groups' in path:
        folder = 'resource_groups'
    if 'floating_ips' in path:
        folder = 'floating_ips'

    return folder


def fake_auth(auth_url, key):
    """
    Return a false header required by authentication process
    """
    return {'Content-Type': 'application/json',
            'Accept': 'application/json',
            'Authorization': 'Bearer <KEY>'}


def fake_get_call(service, verb, path, headers):
    """
    This function will replace the original API.
    """
    result = {}
    result["data"] = {}
    folder = set_folder_var(path)
    result["data"][folder] = []
    resource_file = os.path.normpath('tests/resources/{}/{}.json').format(
        folder,
        folder
    )
    # Must return a file-like object
    try:
        json_file = open(resource_file, mode='rb')
        result["data"][folder].append(json.load(json_file))
        return(result)
    except IOError:
        # return result["data"][folder].append({"error": "not found"})
        raise


def fake_get_one(service, verb, path, headers):
    """
    This function will replace the original API.
    """
    result = {}
    folder = set_folder_var(path)
    resource_file = os.path.normpath('tests/resources/{}/{}.json').format(
        folder,
        folder
    )
    # Must return a file-like object
    try:
        json_file = open(resource_file, mode='rb')
        result["data"] = json.load(json_file)
        return(result)
    except IOError:
        # return["data"]["vpcs"].append({"error": "not found"})
        raise


def fake_create(service, verb, path, headers, payload):
    """
    Test
    """
    data = {}
    # folder = set_folder_var(path)
    if service == "iaas" and verb == "POST":
        data = {"id": "r006-74ff2772-9f3a-4263-bcaa-12fcffa3ed82",
                "crn": "crn:v1:bluemix:public:is:us-south:a/2d171b8a90\
                 e246fd9ffe0e5e8c191c9e::instance:r006-74ff2772-9f3a-4263\
                -bcaa-12fcffa3ed82",
                "href": "https://us-south.iaas.cloud.ibm.com/v1/instances\
                        /r006-74ff2772-9f3a-4263-bcaa-12fcffa3ed82",
                "name": "sdk",
                "status": "available"
                }
        return({"status_code": 200, "data": data})
    else:
        data = {"id": "", "name": "", "status": "error !"}
        return({"status_code": 500, "data": data})


def query_specified_object(path):
    # result = {}
    folder = set_folder_var(path)
    resource_file = os.path.normpath('tests/resources/{}/{}.json').format(
        folder,
        folder
    )
    # Must return a file-like object
    try:
        json_file = open(resource_file, mode='rb')
        result = json.load(json_file)
        return(result)
    except IOError:
        # return["data"]["vpcs"].append({"error": "not found"})
        raise


def fake_get_vpc(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('vpc')
    return(result)


def fake_get_resource_group(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('resource_group')
    return(result)


def fake_get_image(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('image')
    return(result)


def fake_get_vpn(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('vpn')
    return(result)


def fake_get_floating_ip(fake, data):
    """
    This function will replace the original API.
    """
    result = query_specified_object('floating_ips')
    return(result)

Return a false header required by authentication process # @classmethod Set folder variable based on path # @classmethod Will raise an exception Will raise an exception Will raise an exception Will return an not_found error Will return a "not_found" error Will return an not_found error Will return an error (simulate API errors) This function will replace the original qw function. # we want all the data: if the uuid regexp doesn't match but if we pass a string # we should return a  "not_found" error. # we want one record, that one matches the uuid # uuid = re.findall(uuid_regexp, path)[0] This function will replace the qw and will return 404. # we want all the data: if the uuid regexp doesn't match but if we pass a string # we should return a  "not_found" error. # we want one record, that one matches the uuid # uuid = re.findall(uuid_regexp, path)[0] This function will simulate API response # @classmethod This function will get resource group name, href and id from the first         resource record. This function will get resource group name, href and id from the first         resource record. This function will get resource group name, href and id from the first         resource record. Return volume information Return 204 # try: #     resource_file = os.path.normpath('tests/resources/public_gateways/public_gateways.json') #     json_file = open(resource_file, mode='rb') #     json_content = json.load(json_file) # except IOError: #     print("public gateways json file not found") # name = "my-vpc-1" # id = "882a7764-5f0e-43b5-b276-0d1c39189488" Set folder variable based on path Return a false header required by authentication process This function will replace the original API. # Must return a file-like object # return result["data"][folder].append({"error": "not found"}) This function will replace the original API. # Must return a file-like object # return["data"]["vpcs"].append({"error": "not found"}) Test # folder = set_folder_var(path) # result = {} # Must return a file-like object # return["data"]["vpcs"].append({"error": "not found"}) This function will replace the original API. This function will replace the original API. This function will replace the original API. This function will replace the original API. This function will replace the original API.