import time

from threadlocal_aws.clients import route53


def upsert_record(dns_name, record_type, value, ttl=300, wait=True):
    zone_id, change = get_record_change(dns_name, record_type, value, hosted_zones(), ttl=ttl)
    request = route53().change_resource_record_sets(HostedZoneId=zone_id, ChangeBatch={"Changes": [change]})[
        "ChangeInfo"
    ]
    if wait:
        status = route53().get_change(Id=request["Id"])["ChangeInfo"]["Status"]
        while not status == "INSYNC":
            print("Waiting for request to sync - " + str(request["Id"]) + "(" + dns_name + ") status: " + status)
            time.sleep(2)
            status = route53().get_change(Id=request["Id"])["ChangeInfo"]["Status"]


def hosted_zones():
    pages = route53().get_paginator("list_hosted_zones")
    for page in pages.paginate():
        yield from page.get("HostedZones", [])


def longest_matching_zone(alias, hosted_zones):
    ret = {"Name": ""}
    for zone in hosted_zones:
        if (alias + ".").endswith(zone["Name"]) and len(zone["Name"]) > len(ret["Name"]):
            ret = zone
    return ret


def get_record_change(dns_name, record_type, value, hosted_zones, ttl=300):
    zone = longest_matching_zone(dns_name, hosted_zones)
    if zone:
        print(dns_name + " => " + "(" + record_type + ") '" + value + "' in " + zone["Name"])
        change = {
            "Action": "UPSERT",
            "ResourceRecordSet": {
                "Name": dns_name,
                "Type": record_type,
                "TTL": ttl,
                "ResourceRecords": [{"Value": value}],
            },
        }
        return zone["Id"], change
