"""
Copyright 2013 Rackspace

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from cloudcafe.common.tools.datagen import random_int
from cloudcafe.meniscus.common.tools import RequestUtilities


class TenantBehaviors(object):

    def __init__(self, tenant_client, db_client, tenant_config):
        self.tenant_client = tenant_client
        self.db_client = db_client
        self.tenant_config = tenant_config
        self.tenant_ids = []

    def remove_created_tenants(self):
        self.db_client.connect()
        self.db_client.auth()
        for tenant_id in self.tenant_ids:
            self.db_client.remove_tenant(tenant_id)
        self.db_client.disconnect()
        self.tenant_ids = []

    def create_tenant(self, tenant_id=None, use_alternate=False):
        """
        Helper function for creating a tenant on a fixture
        @param self:
        @return: Returns tuple with tenant_id and response object
        """
        if tenant_id is None:
            tenant_id = str(random_int(1, 100000))
        self.tenant_ids.append(tenant_id)

        if use_alternate:
            self.tenant_client.use_alternate = use_alternate

        resp = self.tenant_client.create_tenant(tenant_id)

        if use_alternate:
            self.tenant_client.use_alternate = False
        return tenant_id, resp


class ProducerBehaviors(TenantBehaviors):

    def __init__(self, tenant_client, producer_client, db_client,
                 tenant_config):
        super(ProducerBehaviors, self).__init__(tenant_client=tenant_client,
                                                db_client=db_client,
                                                tenant_config=tenant_config)
        self.producer_client = producer_client
        self.producers_created = []

    def create_producer_from_cfg(self, name=None, pattern=None, durable=None,
                                 encrypted=None):
        """
        @summary: Helper function to create a producer for fixtures. All
        parameters set to None will be loaded from configuration file.
        @return: Dictionary with request object, and producer id
        """

        resp = self.create_producer(
            name=name or self.tenant_config.producer_name,
            pattern=pattern or self.tenant_config.producer_pattern,
            durable=durable or self.tenant_config.producer_durable,
            encrypted=encrypted or self.tenant_config.producer_encrypted)

        return resp

    def create_producer(self, name=None, pattern=None, durable=None,
                        encrypted=None):
        req = self.producer_client.create_producer(
            name=name, pattern=pattern, durable=durable, encrypted=encrypted)

        producer_id = RequestUtilities.get_id(req)
        self.producers_created.append(producer_id)

        return {
            'request': req,
            'producer_id': producer_id
        }

    def delete_producer(self, producer_id, remove_from_array=True):
        response = self.producer_client.delete_producer(producer_id)
        assert response.status_code == 200

        if remove_from_array:
            self.producers_created.remove(producer_id)

        return response


class ProfileBehaviors(ProducerBehaviors):

    def __init__(self, tenant_client, producer_client, profile_client,
                 db_client, tenant_config):
        super(ProfileBehaviors, self).__init__(
            tenant_client=tenant_client,
            producer_client=producer_client,
            db_client=db_client,
            tenant_config=tenant_config)
        self.profile_client = profile_client
        self.profiles_created = []

    def create_profile_from_cfg(self, name=None, producer_ids=None):
        return self.create_profile(
            name=name or self.tenant_config.profile_name,
            producer_ids=producer_ids)

    def create_profile(self, name=None, producer_ids=None):
        profile_req = self.profile_client.create_profile(
            name=name, producer_ids=producer_ids)

        profile_id = RequestUtilities.get_id(profile_req)
        self.profiles_created.append(profile_id)

        return {
            'request': profile_req,
            'profile_id': profile_id
        }

    def delete_profile(self, profile_id, remove_from_array=True):
        response = self.profile_client.delete_profile(profile_id)
        if remove_from_array:
            self.profiles_created.remove(profile_id)

        return response


class HostBehaviors(ProfileBehaviors):

    def __init__(self, tenant_client, producer_client, profile_client,
                 host_client, db_client, tenant_config):
        super(HostBehaviors, self).__init__(
            tenant_client=tenant_client,
            producer_client=producer_client,
            profile_client=profile_client,
            db_client=db_client,
            tenant_config=tenant_config)
        self.host_client = host_client
        self.hosts_created = []

    def delete_host(self, host_id, remove_from_array=True):
        response = self.host_client.delete_host(host_id)

        if remove_from_array:
            self.hosts_created.remove(host_id)

        return response

    def create_host_from_cfg(self, hostname=None, ip_v4=None, ip_v6=None,
                             profile_id=None):
        resp = self.create_host(
            hostname=hostname or self.tenant_config.hostname,
            ip_v4=ip_v4,
            ip_v6=ip_v6,
            profile_id=profile_id)

        return resp

    def create_host(self, hostname, ip_v4=None, ip_v6=None, profile_id=None):
        host_req = self.host_client.create_host(
            hostname=hostname,
            ip_v4=ip_v4,
            ip_v6=ip_v6,
            profile_id=profile_id)

        host_id = RequestUtilities.get_id(host_req)
        self.hosts_created.append(host_id)

        return {
            'request': host_req,
            'host_id': host_id
        }
