from datetime import datetime
import yt.wrapper as yt_wrapper
from datacloud.config.yt import (
    CRYPTA_SNAPSHOT_FOLDER, CRYPTA_DB_LAST_FOLDER
)
from datacloud.dev_utils.time import patterns


__all__ = [
    'get_snapshot',
    'get_future',
    'get_actual'
]


class CryptaSnapshot:
    def __init__(self, root):
        self._root = root
        self._tables = (
            'cid_to_all',
            'email_id_value_to_cid',
            'phone_id_value_to_cid',
            'yuid_to_cid',
        )
        for table in self._tables:
            setattr(self, table, yt_wrapper.ypath_join(self._root, table))

    @property
    def root(self):
        return self._root


def get_snapshot(yt_client, date_str):
    folder = yt_wrapper.ypath_join(CRYPTA_SNAPSHOT_FOLDER, date_str)
    if not yt_client.exists(folder):
        return None
    return CryptaSnapshot(folder)


def get_actual(yt_client, date_str=None):
    if date_str is None:
        date_str = datetime.now().strftime(patterns.FMT_DATE)
    date = get_date_of_actual_snapshot(yt_client, date_str)
    if date:
        return get_snapshot(yt_client, date)
    return None


def get_future(yt_client, date_str):
    return CryptaSnapshot(CRYPTA_DB_LAST_FOLDER)


def get_date_of_actual_snapshot(yt_client, date_str):
    for folder in reversed(yt_client.list(CRYPTA_SNAPSHOT_FOLDER, absolute=True)):
        date = folder.split('/')[-1]
        if date > date_str:
            continue
        candidate = CryptaSnapshot(folder)
        if _exists(yt_client, candidate):
            return date
    return None


def _exists(yt_client, snapshot):
    return all(map(yt_client.exists, (
        snapshot.cid_to_all,
        snapshot.email_id_value_to_cid,
        snapshot.phone_id_value_to_cid,
        snapshot.yuid_to_cid,
    )))
