# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

__all__ = [
    'SoftLayerDNSDriver'
]


from libcloud.common.softlayer import SoftLayerConnection
from libcloud.common.softlayer import SoftLayerObjectDoesntExist
from libcloud.dns.types import Provider, RecordType
from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
from libcloud.dns.base import DNSDriver, Zone, Record


VALID_RECORD_EXTRA_PARAMS = ['priority', 'ttl']


class SoftLayerDNSDriver(DNSDriver):
    type = Provider.SOFTLAYER
    name = 'Softlayer DNS'
    website = 'https://www.softlayer.com'
    connectionCls = SoftLayerConnection

    RECORD_TYPE_MAP = {
        RecordType.A: 'a',
        RecordType.AAAA: 'aaaa',
        RecordType.CNAME: 'cname',
        RecordType.MX: 'mx',
        RecordType.NS: 'ns',
        RecordType.PTR: 'ptr',
        RecordType.SOA: 'soa',
        RecordType.SPF: 'spf',
        RecordType.SRV: 'srv',
        RecordType.TXT: 'txt',
    }

    def create_zone(self, domain, ttl=None, extra=None):
        self.connection.set_context({'resource': 'zone', 'id': domain})
        data = {
            'name': domain,
            'resourceRecords': []
        }
        response = self.connection.request(
            'SoftLayer_Dns_Domain', 'createObject', data
        ).object
        zone = Zone(id=response['id'], domain=domain,
                    type='master', ttl=3600, driver=self)
        return zone

    def get_zone(self, zone_id):
        self.connection.set_context({'resource': 'zone', 'id': zone_id})
        try:
            response = self.connection.request(
                'SoftLayer_Dns_Domain', 'getObject', id=zone_id
            ).object
        except SoftLayerObjectDoesntExist:
            raise ZoneDoesNotExistError(value='', driver=self,
                                        zone_id=zone_id)
        return self._to_zone(response)

    def delete_zone(self, zone):
        self.connection.set_context({'resource': 'zone', 'id': zone.id})
        try:
            self.connection.request(
                'SoftLayer_Dns_Domain', 'deleteObject', id=zone.id
            ).object
        except SoftLayerObjectDoesntExist:
            raise ZoneDoesNotExistError(value='', driver=self,
                                        zone_id=zone.id)
        else:
            return True

    def iterate_zones(self):
        zones_list = self.connection.request(
            'SoftLayer_Dns_Domain', 'getByDomainName', '.'
        ).object
        for item in zones_list:
            yield self._to_zone(item)

    def iterate_records(self, zone):
        self.connection.set_context({'resource': 'zone', 'id': zone.id})
        records_list = self.connection.request(
            'SoftLayer_Dns_Domain', 'getResourceRecords', id=zone.id
        ).object
        for item in records_list:
            yield self._to_record(item, zone=zone)

    def get_record(self, zone_id, record_id):
        try:
            record = self.connection.request(
                'SoftLayer_Dns_Domain_ResourceRecord',
                'getObject',
                id=record_id
            ).object
            return self._to_record(record, zone=self.get_zone(zone_id))
        except SoftLayerObjectDoesntExist:
            raise RecordDoesNotExistError(value='', driver=self,
                                          record_id=record_id)

    def delete_record(self, record):
        try:
            self.connection.request(
                'SoftLayer_Dns_Domain_ResourceRecord',
                'deleteObject',
                id=record.id
            ).object
        except SoftLayerObjectDoesntExist:
            raise RecordDoesNotExistError(value='', driver=self,
                                          record_id=record.id)
        else:
            return True

    def create_record(self, name, zone, type, data, extra=None):
        params = {
            'domainId': zone.id,
            'type': self.RECORD_TYPE_MAP[type],
            'host': name,
            'data': data
        }
        if extra:
            if extra.get('ttl'):
                params['ttl'] = extra['ttl']
            if extra.get('refresh'):
                params['refresh'] = extra['refresh']
            if extra.get('retry'):
                params['retry'] = extra['retry']
            if extra.get('expire'):
                params['expire'] = extra['expire']
            if extra.get('priority'):
                params['mxPriority'] = extra['priority']
        response = self.connection.request(
            'SoftLayer_Dns_Domain_ResourceRecord',
            'createObject',
            params
        ).object

        return self._to_record(response, zone=zone)

    def update_record(
            self, record, name=None, type=None, data=None, extra=None):
        params = {}
        if type:
            params['type'] = self.RECORD_TYPE_MAP[type]
        if name:
            params['host'] = name
        if data:
            params['data'] = data

        if extra:
            if extra.get('ttl'):
                params['ttl'] = extra['ttl']
            if extra.get('refresh'):
                params['refresh'] = extra['refresh']
            if extra.get('retry'):
                params['retry'] = extra['retry']
            if extra.get('expire'):
                params['expire'] = extra['expire']
            if extra.get('priority'):
                params['mxPriority'] = extra['priority']

        response = self.connection.request(
            'SoftLayer_Dns_Domain_ResourceRecord',
            'editObject',
            params,
            id=record.id,
        ).object

        if response:
            changed_record = self.connection.request(
                'SoftLayer_Dns_Domain_ResourceRecord',
                'getObject',
                id=record.id,
            ).object
            return self._to_record(changed_record, zone=record.zone)
        else:
            return False

    def _to_zone(self, item):
        ttl = item.get('ttl', 3600)
        zone = Zone(id=item['id'], domain=item['name'],
                    type='master', ttl=ttl, driver=self)
        return zone

    def _to_record(self, item, zone=None):
        extra = {
            'ttl': item['ttl'],
            'expire': item['expire'],
            'mxPriority': item['mxPriority'],
            'refresh': item['refresh'],
            'retry': item['retry'],
        }
        record = Record(
            id=item['id'],
            name=item['host'],
            type=self._string_to_record_type(item['type']),
            data=item['data'],
            zone=zone,
            driver=self,
            extra=extra
        )
        return record
