import os
from logging import getLogger
from uuid import uuid4

from intranet.search.yt.jobs import BaseJob


log = getLogger(__name__)


class Job(BaseJob):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.base_path = os.path.join(self.common_table_prefix, 'data', self.options['env'])

    def merge_rows(self, key_row, rows):
        # Просто для всех записей по одному документу берем запись самым поздним временем
        row = max(rows, key=lambda x: x['timestamp'])
        yield row

    def run_merge(self, tables, destination_table):
        return self.yt.run_map_reduce(
            mapper=None,
            reducer=self.merge_rows,
            source_table=tables,
            destination_table=destination_table,
            reduce_by=['url'],
            sync=True,
        )

    def run(self, tables):
        errors = []

        for destination, sources in tables.items():
            log.debug('Start merging tables to %s', destination)
            try:
                # существующую таблицу назначения нужно тоже смержить с остальными
                if self.yt.exists(destination) and destination not in sources:
                    sources.append(destination)

                if len(sources) == 1:
                    # если нужно смержить только одну таблицу, то фактический мерж не нужен:
                    # если сама таблица и есть таблица в которую мержим - то не делаем ничего
                    # иначе просто переименуем одну в другую
                    if sources[0] == destination:
                        log.debug('Nothing to do, just keep %s', destination)
                        continue
                    else:
                        log.debug('Nothing to merge, just move %s to %s', sources[0], destination)
                        self.yt.move(sources[0], destination)
                else:
                    tmp_destination = destination + '-tmp' + uuid4().hex
                    try:
                        self.run_merge(sources, tmp_destination)
                    except Exception as e:
                        log.exception(e)
                        self.yt.remove(tmp_destination, force=True)
                    else:
                        # удаляем смерженные таблицы
                        for tbl in sources:
                            self.yt.remove(tbl, force=True)
                        # переносим данные из временной таблицы в постоянную
                        self.yt.move(tmp_destination, destination)
            except Exception as e:
                log.exception(e)
                errors.append(str(e))

        if errors:
            raise Exception('\n'.join(errors))
