#!/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 _auth():
    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=""):
    '''
    Get DNS zone extraction

    zone
        Zone name to fetch
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    client = _auth()
    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=""):
    '''
    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
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    client = _auth()
    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):
    '''
    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
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    client = _auth()
    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):
    '''
    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
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    client = _auth()
    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:
                    req = client.put(f'/domain/zone/{zone}/record/{rec}',
                                     subDomain=subDomain,
                                     target=target,
                                     ttl=ttl)
                    return req
        return "Error updating record"
    except APIError:
        return "Query failed in OVH API"

    return None


def domain_delete_record(zone="", fieldType="", subDomain=""):
    '''
    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)
    '''

    if zone == "":
        raise ArgumentValueError("Zone is not defined")
    results = []
    client = _auth()
    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=""):
    '''
    Apply zone modification on DNS servers

    zone
        The internal name of your zone
    '''

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

    return req