# 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.
"""
World Wide DNS Driver
"""

__all__ = ["WorldWideDNSDriver"]

import re

from libcloud.common.types import LibcloudError
from libcloud.common.worldwidedns import WorldWideDNSConnection
from libcloud.dns.types import Provider, RecordType
from libcloud.dns.types import ZoneDoesNotExistError
from libcloud.dns.types import RecordError
from libcloud.dns.types import RecordDoesNotExistError
from libcloud.dns.base import DNSDriver, Zone, Record


MAX_RECORD_ENTRIES = 40  # Maximum record entries for zone


class WorldWideDNSError(LibcloudError):
    def __repr__(self):
        return (
            "<WorldWideDNSError in " + repr(self.driver) + " " + repr(self.value) + ">"
        )


class WorldWideDNSDriver(DNSDriver):
    type = Provider.WORLDWIDEDNS
    name = "World Wide DNS"
    website = "https://www.worldwidedns.net/"
    connectionCls = WorldWideDNSConnection

    RECORD_TYPE_MAP = {
        RecordType.MX: "MX",
        RecordType.CNAME: "CNAME",
        RecordType.A: "A",
        RecordType.NS: "NS",
        RecordType.SRV: "SRV",
        RecordType.TXT: "TXT",
    }

    def __init__(
        self,
        key,
        secret=None,
        reseller_id=None,
        secure=True,
        host=None,
        port=None,
        **kwargs,
    ):
        """
        :param    key: API key or username to used (required)
        :type     key: ``str``

        :param    secret: Secret password to be used (required)
        :type     secret: ``str``

        :param    reseller_id: Reseller ID for reseller accounts
        :type     reseller_id: ``str``

        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
                          only support HTTPS, and it is on by default.
        :type     secure: ``bool``

        :param    host: Override hostname used for connections.
        :type     host: ``str``

        :param    port: Override port used for connections.
        :type     port: ``int``

        :return: ``None``
        """
        super(WorldWideDNSDriver, self).__init__(
            key=key, secret=secret, secure=secure, host=host, port=port, **kwargs
        )
        self.reseller_id = reseller_id

    def list_zones(self):
        """
        Return a list of zones.

        :return: ``list`` of :class:`Zone`

        For more info, please see:
        https://www.worldwidedns.net/dns_api_protocol_list.asp
        or
        https://www.worldwidedns.net/dns_api_protocol_list_reseller.asp
        """
        action = "/api_dns_list.asp"
        if self.reseller_id is not None:
            action = "/api_dns_list_reseller.asp"
        zones = self.connection.request(action)
        if len(zones.body) == 0:
            return []
        else:
            return self._to_zones(zones.body)

    def iterate_records(self, zone):
        """
        Return a generator to iterate over records for the provided zone.

        :param zone: Zone to list records for.
        :type zone: :class:`Zone`

        :rtype: ``generator`` of :class:`Record`
        """
        records = self._to_records(zone)
        for record in records:
            yield record

    def get_zone(self, zone_id):
        """
        Return a Zone instance.

        :param zone_id: ID of the required zone
        :type  zone_id: ``str``

        :rtype: :class:`Zone`
        """
        zones = self.list_zones()
        zone = [zone for zone in zones if zone.id == zone_id]
        if len(zone) == 0:
            raise ZoneDoesNotExistError(
                driver=self, value="The zone doesn't exists", zone_id=zone_id
            )
        return zone[0]

    def get_record(self, zone_id, record_id):
        """
        Return a Record instance.

        :param zone_id: ID of the required zone
        :type  zone_id: ``str``

        :param record_id: ID number of the required record.
        :type  record_id: ``str``

        :rtype: :class:`Record`
        """
        zone = self.get_zone(zone_id)
        try:
            if int(record_id) not in range(1, MAX_RECORD_ENTRIES + 1):
                raise RecordDoesNotExistError(
                    value="Record doesn't exists",
                    driver=zone.driver,
                    record_id=record_id,
                )
        except ValueError:
            raise WorldWideDNSError(
                value="Record id should be a string number", driver=self
            )
        subdomain = zone.extra.get("S%s" % record_id)
        type = zone.extra.get("T%s" % record_id)
        data = zone.extra.get("D%s" % record_id)
        record = self._to_record(record_id, subdomain, type, data, zone)
        return record

    def update_zone(
        self, zone, domain, type="master", ttl=None, extra=None, ex_raw=False
    ):
        """
        Update an existing zone.

        :param zone: Zone to update.
        :type  zone: :class:`Zone`

        :param domain: Zone domain name (e.g. example.com)
        :type  domain: ``str``

        :param type: Zone type (master / slave).
        :type  type: ``str``

        :param ttl: TTL for new records. (optional)
        :type  ttl: ``int``

        :param extra: Extra attributes (driver specific) (optional). Values not
                      specified such as *SECURE*, *IP*, *FOLDER*, *HOSTMASTER*,
                      *REFRESH*, *RETRY* and *EXPIRE* will be kept as already
                      is. The same will be for *S(1 to 40)*, *T(1 to 40)* and
                      *D(1 to 40)* if not in raw mode and for *ZONENS* and
                      *ZONEDATA* if it is.
        :type  extra: ``dict``

        :param ex_raw: Mode we use to do the update using zone file or not.
        :type  ex_raw: ``bool``

        :rtype: :class:`Zone`

        For more info, please see
        https://www.worldwidedns.net/dns_api_protocol_list_domain.asp
        or
        https://www.worldwidedns.net/dns_api_protocol_list_domain_raw.asp
        or
        https://www.worldwidedns.net/dns_api_protocol_list_domain_reseller.asp
        or
        https://www.worldwidedns.net/dns_api_protocol_list_domain_raw_reseller.asp
        """
        if extra is not None:
            not_specified = [
                key for key in zone.extra.keys() if key not in extra.keys()
            ]
        else:
            not_specified = zone.extra.keys()

        if ttl is None:
            ttl = zone.ttl

        params = {"DOMAIN": domain, "TTL": ttl}

        for key in not_specified:
            params[key] = zone.extra[key]
        if extra is not None:
            params.update(extra)
        if ex_raw:
            action = "/api_dns_modify_raw.asp"
            if self.reseller_id is not None:
                action = "/api_dns_modify_raw_reseller.asp"
            method = "POST"
        else:
            action = "/api_dns_modify.asp"
            if self.reseller_id is not None:
                action = "/api_dns_modify_reseller.asp"
            method = "GET"
        response = self.connection.request(action, params=params, method=method)  # noqa
        zone = self.get_zone(zone.id)
        return zone

    def update_record(self, record, name, type, data, extra=None):
        """
        Update an existing record.

        :param record: Record to update.
        :type  record: :class:`Record`

        :param name: Record name without the domain name (e.g. www).
                     Note: If you want to create a record for a base domain
                     name, you should specify empty string ('') for this
                     argument.
        :type  name: ``str``

        :param type: DNS record type (MX, CNAME, A, NS, SRV, TXT).
        :type  type: :class:`RecordType`

        :param data: Data for the record (depends on the record type).
        :type  data: ``str``

        :param extra: Contains 'entry' Entry position (1 thru 40)
        :type extra: ``dict``

        :rtype: :class:`Record`
        """
        if (extra is None) or ("entry" not in extra):
            raise WorldWideDNSError(
                value="You must enter 'entry' parameter", driver=self
            )
        record_id = extra.get("entry")
        if name == "":
            name = "@"
        if type not in self.RECORD_TYPE_MAP:
            raise RecordError(
                value="Record type is not allowed",
                driver=record.zone.driver,
                record_id=name,
            )
        zone = record.zone
        extra = {
            "S%s" % record_id: name,
            "T%s" % record_id: type,
            "D%s" % record_id: data,
        }
        zone = self.update_zone(zone, zone.domain, extra=extra)
        record = self.get_record(zone.id, record_id)
        return record

    def create_zone(self, domain, type="master", ttl=None, extra=None):
        """
        Create a new zone.

        :param domain: Zone domain name (e.g. example.com)
        :type domain: ``str``

        :param type: Zone type (master / slave).
        :type  type: ``str``

        :param ttl: TTL for new records. (optional)
        :type  ttl: ``int``

        :param extra: Extra attributes (driver specific). (optional). Possible
                      parameter in here should be *DYN* which values should be
                      1 for standart and 2 for dynamic. Default is 1.
        :type extra: ``dict``

        :rtype: :class:`Zone`

        For more info, please see
        https://www.worldwidedns.net/dns_api_protocol_new_domain.asp
        or
        https://www.worldwidedns.net/dns_api_protocol_new_domain_reseller.asp
        """
        if type == "master":
            _type = 0
        elif type == "slave":
            _type = 1
        if extra:
            dyn = extra.get("DYN") or 1
        else:
            dyn = 1
        params = {"DOMAIN": domain, "TYPE": _type}
        action = "/api_dns_new_domain.asp"
        if self.reseller_id is not None:
            params["DYN"] = dyn
            action = "/api_dns_new_domain_reseller.asp"
        self.connection.request(action, params=params)
        zone = self.get_zone(domain)
        if ttl is not None:
            zone = self.update_zone(zone, zone.domain, ttl=ttl)
        return zone

    def create_record(self, name, zone, type, data, extra=None):
        """
        Create a new record.

        We can create 40 record per domain. If all slots are full, we can
        replace one of them by choosing a specific entry in ``extra`` argument.

        :param name: Record name without the domain name (e.g. www).
                     Note: If you want to create a record for a base domain
                     name, you should specify empty string ('') for this
                     argument.
        :type  name: ``str``

        :param zone: Zone where the requested record is created.
        :type  zone: :class:`Zone`

        :param type: DNS record type (MX, CNAME, A, NS, SRV, TXT).
        :type  type: :class:`RecordType`

        :param data: Data for the record (depends on the record type).
        :type  data: ``str``

        :param extra: Contains 'entry' Entry position (1 thru 40)
        :type extra: ``dict``

        :rtype: :class:`Record`
        """
        if (extra is None) or ("entry" not in extra):
            # If no entry is specified, we look for an available one. If all
            # are full, raise error.
            record_id = self._get_available_record_entry(zone)
            if not record_id:
                raise WorldWideDNSError(
                    value="All record entries are full", driver=zone.driver
                )
        else:
            record_id = extra.get("entry")
        if name == "":
            name = "@"
        if type not in self.RECORD_TYPE_MAP:
            raise RecordError(
                value="Record type is not allowed",
                driver=zone.driver,
                record_id=record_id,
            )
        extra = {
            "S%s" % record_id: name,
            "T%s" % record_id: type,
            "D%s" % record_id: data,
        }
        zone = self.update_zone(zone, zone.domain, extra=extra)
        record = self.get_record(zone.id, record_id)
        return record

    def delete_zone(self, zone):
        """
        Delete a zone.

        Note: This will delete all the records belonging to this zone.

        :param zone: Zone to delete.
        :type  zone: :class:`Zone`

        :rtype: ``bool``

        For more information, please see
        https://www.worldwidedns.net/dns_api_protocol_delete_domain.asp
        or
        https://www.worldwidedns.net/dns_api_protocol_delete_domain_reseller.asp
        """
        params = {"DOMAIN": zone.domain}
        action = "/api_dns_delete_domain.asp"
        if self.reseller_id is not None:
            action = "/api_dns_delete_domain_reseller.asp"
        response = self.connection.request(action, params=params)
        return response.success()

    def delete_record(self, record):
        """
        Delete a record.

        :param record: Record to delete.
        :type  record: :class:`Record`

        :rtype: ``bool``
        """
        zone = record.zone
        for index in range(MAX_RECORD_ENTRIES):
            if record.name == zone.extra["S%s" % (index + 1)]:
                entry = index + 1
                break
        extra = {"S%s" % entry: "", "T%s" % entry: "NONE", "D%s" % entry: ""}
        self.update_zone(zone, zone.domain, extra=extra)
        return True

    def ex_view_zone(self, domain, name_server):
        """
        View zone file from a name server

        :param domain: Domain name.
        :type  domain: ``str``

        :param name_server: Name server to check. (1, 2 or 3)
        :type  name_server: ``int``

        :rtype: ``str``

        For more info, please see:
        https://www.worldwidedns.net/dns_api_protocol_viewzone.asp
        or
        https://www.worldwidedns.net/dns_api_protocol_viewzone_reseller.asp
        """
        params = {"DOMAIN": domain, "NS": name_server}
        action = "/api_dns_viewzone.asp"
        if self.reseller_id is not None:
            action = "/api_dns_viewzone_reseller.asp"
        response = self.connection.request(action, params=params)
        return response.object

    def ex_transfer_domain(self, domain, user_id):
        """
        This command will allow you, if you are a reseller, to change the
        userid on a domain name to another userid in your account ONLY if that
        new userid is already created.

        :param domain: Domain name.
        :type  domain: ``str``

        :param user_id: The new userid to connect to the domain name.
        :type  user_id: ``str``

        :rtype: ``bool``

        For more info, please see:
        https://www.worldwidedns.net/dns_api_protocol_transfer.asp
        """
        if self.reseller_id is None:
            raise WorldWideDNSError("This is not a reseller account", driver=self)
        params = {"DOMAIN": domain, "NEW_ID": user_id}
        response = self.connection.request("/api_dns_transfer.asp", params=params)
        return response.success()

    def _get_available_record_entry(self, zone):
        """Return an available entry to store a record."""
        entries = zone.extra
        for entry in range(1, MAX_RECORD_ENTRIES + 1):
            subdomain = entries.get("S%s" % entry)
            _type = entries.get("T%s" % entry)
            data = entries.get("D%s" % entry)
            if not any([subdomain, _type, data]):
                return entry
        return None

    def _to_zones(self, data):
        domain_list = re.split("\r?\n", data)
        zones = []
        for line in domain_list:
            zone = self._to_zone(line)
            zones.append(zone)

        return zones

    def _to_zone(self, line):
        data = line.split("\x1f")
        name = data[0]
        if data[1] == "P":
            type = "master"
            domain_data = self._get_domain_data(name)
            resp_lines = re.split("\r?\n", domain_data.body)
            soa_block = resp_lines[:6]
            zone_data = resp_lines[6:]
            extra = {
                "HOSTMASTER": soa_block[0],
                "REFRESH": soa_block[1],
                "RETRY": soa_block[2],
                "EXPIRE": soa_block[3],
                "SECURE": soa_block[5],
            }
            ttl = soa_block[4]
            for line in range(MAX_RECORD_ENTRIES):
                line_data = zone_data[line].split("\x1f")
                extra["S%s" % (line + 1)] = line_data[0]
                _type = line_data[1]
                extra["T%s" % (line + 1)] = _type if _type != "NONE" else ""
                try:
                    extra["D%s" % (line + 1)] = line_data[2]
                except IndexError:
                    extra["D%s" % (line + 1)] = ""
        elif data[1] == "S":
            type = "slave"
            extra = {}
            ttl = 0
        return Zone(id=name, domain=name, type=type, ttl=ttl, driver=self, extra=extra)

    def _get_domain_data(self, name):
        params = {"DOMAIN": name}
        data = self.connection.request("/api_dns_list_domain.asp", params=params)
        return data

    def _to_records(self, zone):
        records = []
        for record_id in range(1, MAX_RECORD_ENTRIES + 1):
            subdomain = zone.extra["S%s" % (record_id)]
            type = zone.extra["T%s" % (record_id)]
            data = zone.extra["D%s" % (record_id)]
            if subdomain and type and data:
                record = self._to_record(record_id, subdomain, type, data, zone)
                records.append(record)
        return records

    def _to_record(self, _id, subdomain, type, data, zone):
        return Record(
            id=_id, name=subdomain, type=type, data=data, zone=zone, driver=zone.driver
        )
