#!/usr/bin/python3

import salt
import ovh

from salt.exceptions import CommandExecutionError, ArgumentValueError
from ovh.exceptions import ResourceNotFoundError, APIError


def __virtual__():
    return True


def _config():
    config = __salt__['config.get']('ovh')
    if not config:
        raise CommandExecutionError(
            'OVH execution module configuration could not be found'
        )

    return config


def authenticate():
    cfg = _config()
    client = ovh.Client(
        endpoint=cfg['endpoint'],
        application_key=cfg['application_key'],
        application_secret=cfg['application_secret'],
        consumer_key=cfg['consumer_key'],
    )

    return client


def domain_get_zone(zone="",
                    client=None):
    '''
    Get DNS zone extraction

    zone
        Zone name to fetch
    client
        Client to use against API
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    try:
        results = client.get(f'/domain/zone/{zone}/export')
    except APIError:
        return "Query failed in OVH API"

    return results


def domain_get_record(zone="",
                      fieldType="",
                      subDomain="",
                      target="",
                      client=None):
    '''
    Record of the zone

    zone
        Zone name to fetch
    fieldType
        Filter the value of fieldType property (like)
    subDomain
        Filter the value of subDomain property (like)
    target
        Resource record target
    client
        Client to use against API
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    try:
        records = client.get(f'/domain/zone/{zone}/record',
                             fieldType=fieldType,
                             subDomain=subDomain)
        if len(records) > 0:
            for rec in records:
                res = client.get(f'/domain/zone/{zone}/record/{rec}')
                if res['target'] == target:
                    return res
    except APIError:
        return "Query failed in OVH API"
    return None


def domain_post_record(zone="",
                       fieldType="",
                       subDomain="",
                       target="",
                       ttl=0,
                       client=None):
    '''
    Create a new DNS record

    zone
        The internal name of your zone
    fieldType
        Filter the value of fieldType property (like)
    subDomain
        Filter the value of subDomain property (like)
    target
        Resource record target
    ttl
        Resource record ttl
    client
        Client to use against API
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    try:
        req = client.post(f'/domain/zone/{zone}/record',
                          fieldType=fieldType,
                          subDomain=subDomain,
                          target=target,
                          ttl=ttl)
    except APIError:
        return "Query failed in OVH API"

    return req


def domain_put_record(zone="",
                      fieldType="",
                      subDomain="",
                      target="",
                      ttl=0,
                      current=None,
                      client=None):
    '''
    Update a DNS record

    zone
        The internal name of your zone
    fieldType
        Filter the value of fieldType property (like)
    subDomain
        Filter the value of subDomain property (like)
    target
        Resource record target
    ttl
        Resource record ttl
    current
        Current DNS record
    client
        Client to use against API
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    try:
        client.put(f'/domain/zone/{zone}/record/{current["id"]}',
                   subDomain=subDomain,
                   target=target,
                   ttl=ttl)
        changed = client.get(f'/domain/zone/{zone}/record/{current["id"]}')
    except APIError:
        return "Query failed in OVH API"
    return changed


def domain_delete_record(zone="",
                         fieldType="",
                         subDomain="",
                         client=None):
    '''
    Delete a DNS record (Don't forget to refresh the zone)

    zone
        The internal name of your zone
    fieldType
        Filter the value of fieldType property (like)
    subDomain
        Filter the value of subDomain property (like)
    client
        Client to use against API
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    results = []
    try:
        records = client.get(f'/domain/zone/{zone}/record',
                             fieldType=fieldType,
                             subDomain=subDomain)
    except APIError:
        return "Query failed in OVH API"
    for record in records:
        try:
            req = client.delete(f'/domain/zone/{zone}/record/{record}')
            results.append(req)
        except ResourceNotFoundError:
            return "Resource not found in OVH API"

    return results


def domain_refresh_zone(zone="",
                        client=None):
    '''
    Apply zone modification on DNS servers

    zone
        The internal name of your zone
    client
        Client to use against API
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    try:
        req = client.post(f'/domain/zone/{zone}/refresh')
    except APIError:
        return "Query failed in OVH API"

    return req