from yt.wrapper import ypath_join
import yt.wrapper as yt_wrapper
from datacloud.launcher.lib.services_logs.helpers import YqlLogFilter
from datacloud.dev_utils.logging.logger import get_basic_logger

logger = get_basic_logger(__name__)

ROUTER_LOG_PATH = '//home/logfeller/logs/qloud-router-log'

ROUTER_LOG_SCHEMA = [
    {"name": "ts", "type": "string"},
    {"name": "datetime", "type": "string"},
    {"name": "vhost", "type": "string"},
    {"name": "request", "type": "string"},
    {"name": "cookies", "type": "string"},
    {"name": "ip", "type": "string"},
    {"name": "referer", "type": "string"},
    {"name": "user_agent", "type": "string"},
    {"name": "status", "type": "string"},
    {"name": "request_id", "type": "string"},
    {"name": "nginx_request_length", "type": "string"},
    {"name": "nginx_bytes_sent", "type": "string"},
    {"name": "nginx_upstream_addr", "type": "string"},
    {"name": "nginx_upstream_response_time", "type": "string"},
    {"name": "nginx_request_time", "type": "string"},
    {"name": "nginx_scheme", "type": "string"},
    {"name": "nginx_request_method", "type": "string"},
    {"name": "qloud_router_instance_name", "type": "string"},
    {"name": "qloud_router_name", "type": "string"},
    {"name": "qloud_project", "type": "string"},
    {"name": "qloud_application", "type": "string"},
    {"name": "qloud_environment", "type": "string"},
    {"name": "qloud_instance", "type": "string"},
    {"name": "balancer_type", "type": "string"}
]


class RawLogFilterRouter(YqlLogFilter):
    """ Manipulates raw router log from x-products services """

    def __init__(self, *args, **kwargs):
        super(RawLogFilterRouter, self).__init__()
        self._tables = RouterLogTables(*args, **kwargs)

    def grep_stream_tables(self, table_pathes):
        """ Filters table like "//home/logfeller/logs/router-runtime-log/stream/5min/2017-10-18T15:20:00" """
        query = """
            INSERT INTO `%(output_table)s`
            SELECT
                ts,
                `datetime`,
                request,
                ip,
                user_agent,
                status,
                request_id,
                nginx_request_length,
                nginx_bytes_sent,
                nginx_upstream_addr,
                nginx_upstream_response_time,
                nginx_request_time,
                nginx_scheme,
                nginx_request_method,
                qloud_router_instance_name,
                qloud_project,
                qloud_application,
                qloud_environment,
                qloud_instance,
                balancer_type

            FROM `%(input_table)s`
            WHERE qloud_project = 'x-products' and qloud_application = 'datacloud-score-api';"""
        return super(RawLogFilterRouter, self).grep_stream_tables(query, table_pathes)

    def list_unfiltered_stream(self):
        return self.yt_list(ypath_join(ROUTER_LOG_PATH, 'stream/5min'))

    def list_filtered_stream(self):
        yield self._tables.logs_history_path, self.yt_list(self._tables.raw_logs_stream_path)

    def get_yt_client(self):
        return self._tables.yt_client

    def get_stream_output_tables(self, time_str):
        yield self._tables.get_raw_stream_table(time_str)


def _build_filter_qloud_project_mapper(project, app_blacklist):
    def mapper(record):
        if record['qloud_project'] != project:
            raise StopIteration()
        if record['qloud_application'] in app_blacklist:
            raise StopIteration()
        yield record
    return mapper


class RouterLogTables:

    def __init__(self, root):
        self._root = root
        raw_logs_path = str(ypath_join(root, 'services/logs/router'))
        self.raw_logs_stream_path = str(ypath_join(raw_logs_path, 'stream/5min'))
        self.logs_history_path = str(ypath_join(raw_logs_path, 'history'))

    def get_raw_stream_table(self, table_name):
        return yt_wrapper.TablePath(
            ypath_join(self.raw_logs_stream_path, table_name),
            attributes={
                'schema': ROUTER_LOG_SCHEMA
            }
        )
