# coding: utf-8

import os
import random
from copy import deepcopy

from json import loads

# noinspection PyUnresolvedReferences
from django_replicated.settings import *

from . import IS_DEVELOPMENT, ds, ref


# ------------------------------------------------------------------------------
# Compute list of hosts


def sort_hosts(dcs: dict, current_dc: str, db_hosts: dict) -> str:
    """
    :param dcs: mapping DC to a list of other DCs in a preferred order
    :param current_dc: current instance DC
    :param db_hosts: list of hosts as returned by `yc mdb cluster ListHosts`
    :return: comma-separated list of hosts
    """

    try:
        preferred = dcs[current_dc]
    except KeyError:
        # Use random order when the current DC is unknown or undefined
        preferred = list(dcs.keys())
        random.shuffle(preferred)

    # Map DCs to ranks. The less the more preferred.
    dc_ranks = {dc: rank for rank, dc in enumerate(preferred)}

    # List of (host, geo) pairs.
    # `geo` is set to None if undefined.
    hosts = [
        (host['name'], host.get('options', {}).get('geo')) for host in db_hosts
    ]

    # Sort hosts by ranks of their DCs.
    # Use random ranks when a host DC is unknown or undefined
    hosts.sort(
        key=lambda x: dc_ranks.get(x[1], random.randrange(0, len(dcs) + 1))
    )

    return ','.join(host for host, geo in hosts)


dcs_by_distance = {
    'iva': ('iva', 'myt', 'vla', 'sas', 'man'),
    'myt': ('myt', 'iva', 'vla', 'sas', 'man'),
    'sas': ('sas', 'vla', 'iva', 'myt', 'man'),
    'vla': ('vla', 'iva', 'myt', 'sas', 'man'),
    'man': ('man', 'myt', 'iva', 'vla', 'sas'),
}


host_string = sort_hosts(
    dcs_by_distance,
    os.getenv('DEPLOY_NODE_DC', '').lower(),
    loads(ds.db_hosts)['hosts'],
)

# ------------------------------------------------------------------------------
# Set up db profiles

profile_common = {
    'ENGINE': 'django_pgaas.backend',
    'HOST': host_string,
    'PORT': ds.db_port,
    'USER': ds.db_user,
    'PASSWORD': ds.db_password,
    'NAME': ds.db_name,
    'ATOMIC_REQUESTS': True,
    'CONN_MAX_AGE': 600,
    'OPTIONS': {},
    'DISABLE_SERVER_SIDE_CURSORS': True,
    'TEST': {'SERIALIZE': False},
}


if IS_DEVELOPMENT:
    PGAAS_COLLATION = ''


if not IS_DEVELOPMENT:
    profile_common['OPTIONS'].update(
        {'sslmode': 'verify-full', 'sslrootcert': ref('INTERNAL_ROOT_CA')}
    )

DATABASES = {}

# Default profile
profile = deepcopy(profile_common)
profile['OPTIONS']['target_session_attrs'] = 'read-write'
DATABASES['default'] = profile

# Slave profile
profile = deepcopy(profile_common)
profile['OPTIONS']['target_session_attrs'] = 'any'
DATABASES['slave'] = profile

# ------------------------------------------------------------------------------

REPLICATED_DATABASE_SLAVES = ['slave']
REPLICATED_CHECK_STATE_ON_WRITE = False

DATABASE_ROUTERS = ['django_replicated.router.ReplicationRouter']
