# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
# Author: Endre Karlson <endre.karlson@hp.com>
#
# 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 rally.task import atomic

from rally_openstack.task import scenario


class DesignateScenario(scenario.OpenStackScenario):
    """Base class for Designate scenarios with basic atomic actions."""

    # valid domain name cannot contain underscore characters
    # which are used in default autogenerated names
    RESOURCE_NAME_FORMAT = "s-rally-XXXXXXXX-XXXXXXXX"

    @atomic.action_timer("designate.create_zone")
    def _create_zone(self, name=None, type_=None, email=None, description=None,
                     ttl=None):
        """Create zone.

        :param name: Zone name
        :param type_: Zone type, PRIMARY or SECONDARY
        :param email: Zone owner email
        :param description: Zone description
        :param ttl: Zone ttl - Time to live in seconds
        :returns: designate zone dict
        """
        type_ = type_ or "PRIMARY"

        if type_ == "PRIMARY":
            email = email or "root@random.name"
            # Name is only useful to be random for PRIMARY
            name = name or "%s.name." % self.generate_random_name()

        return self.clients("designate", version="2").zones.create(
            name=name,
            type_=type_,
            email=email,
            description=description,
            ttl=ttl
        )

    @atomic.action_timer("designate.list_zones")
    def _list_zones(self, criterion=None, marker=None, limit=None):
        """Return user zone list.

        :param criterion: API Criterion to filter by
        :param marker: UUID marker of the item to start the page from
        :param limit: How many items to return in the page.
        :returns: list of designate zones
        """
        return self.clients("designate", version="2").zones.list()

    @atomic.action_timer("designate.delete_zone")
    def _delete_zone(self, zone_id):
        """Delete designate zone.

        :param zone_id: Zone ID
        """
        self.clients("designate", version="2").zones.delete(zone_id)

    @atomic.action_timer("designate.list_recordsets")
    def _list_recordsets(self, zone_id, criterion=None, marker=None,
                         limit=None):
        """List zone recordsets.

        :param zone_id: Zone ID
        :param criterion: API Criterion to filter by
        :param marker: UUID marker of the item to start the page from
        :param limit: How many items to return in the page.
        :returns: zone recordsets list
        """
        return self.clients("designate", version="2").recordsets.list(
            zone_id, criterion=criterion, marker=marker, limit=limit)

    @atomic.action_timer("designate.create_recordset")
    def _create_recordset(self, zone, recordset=None):
        """Create a recordset in a zone.

        :param zone: zone dict
        :param recordset: recordset dict
        :returns: Designate recordset dict
        """
        recordset = recordset or {}
        recordset.setdefault("type_", recordset.pop("type", "A"))
        if "name" not in recordset:
            recordset["name"] = "%s.%s" % (self.generate_random_name(),
                                           zone["name"])
        if "records" not in recordset:
            recordset["records"] = ["10.0.0.1"]

        return self.clients("designate", version="2").recordsets.create(
            zone["id"], **recordset)

    @atomic.action_timer("designate.delete_recordset")
    def _delete_recordset(self, zone_id, recordset_id):
        """Delete a zone recordset.

        :param zone_id: Zone ID
        :param recordset_id: Recordset ID
        """

        self.clients("designate", version="2").recordsets.delete(
            zone_id, recordset_id)
