import click
import yt.wrapper as yt
from datacloud.geo.lib import (
    olap, geo_log_utils, general
)
from datacloud.geo.app.olap import data, download


@click.group()
def cli():
    pass


@cli.command('yuid-to-socdem')
@click.option('--output-table', required=True)
def yuid_to_socdem(output_table):
    """This shoud convert yandexuid socdem table
       `//home/crypta/production/profiles/export/profiles_for_14days`
       to yuid table and save result in `output_table`
    """
    crypta_socdem_table = '//home/crypta/production/profiles/export/profiles_for_14days'
    yt.run_map(general.yandexuid_to_yuid_mapper, crypta_socdem_table, output_table)


@cli.command('latlon-to-geo-id')  # geo-log-to-grid
@click.option('--geo-log-table', required=True)
@click.option('--output-table', required=True)
@click.option('--resolution', type=int, default=9)
def latlon_to_geo_id(geo_log_table, output_table, resolution):
    """This should convert (lat, lon) coords to geo_id (h3 geohash)
    By default grid is limited to Msc and Spb, can be changes in function source

    --geo-log-tables - YT table, wich contains `lat`, `lon, and other columns
    --output-table - path to YT table to save result: `geo_id` and other columns
    --resolution - h3 hash resolution, default is 9
    """
    is_moscow = lambda lat, lon: 36.731747 < lon < 37.978694 and 55.110662 < lat < 56.056009
    is_spb = lambda lat, lon: 29.421677 < lon < 30.756515 and 59.597655 < lat < 60.248705
    is_good_point = lambda lat, lon: is_moscow(lat, lon) or is_spb(lat, lon)
    geo_log_utils.geo_log_to_grid_h3(yt, geo_log_table, output_table, resolution, is_good_point)


@cli.command('build-polygon-base')
@click.option('--geo-id-table', required=True)
@click.option('--output-table', required=True)
def build_polygon_base(geo_id_table, output_table):
    """This should build polygon-base table from geo-id table.
    Polygon base table contains polygon hashes and coordinates for different resolutions
    and additional information from GeoBase

    --geo-id-table - YT table with geo_id field
    --output-table - YT table to save result polygons
    """
    olap.get_polygon_base(yt, geo_id_table, output_table)
    yt.run_sort(output_table, sort_by='geo_id')


@cli.command('build-olap')
@click.option('--yuid-to-socdem-table', required=True)
@click.option('--yuid-to-geo-id-table', required=True)
@click.option('--polygon-base-table', required=True)
@click.option('--output-table', required=True)
def build_olap(yuid_to_socdem_table, yuid_to_geo_id_table, polygon_base_table, output_table):
    """This should build OLAP cube from socdem and geo_id tables
    """
    with yt.TempTable() as tmp_base_olap_table:
        olap.olap_transformer_with_counters(yt, yuid_to_geo_id_table, yuid_to_socdem_table, data.INTERESTS, tmp_base_olap_table)
        geo_log_utils.enhance_geo_id_with_city(yt, tmp_base_olap_table, polygon_base_table, output_table)


@cli.command('download-olap')
@click.option('--table', required=True)
@click.option('--local-file', required=True)
def download_olap(table, local_file):
    """This should download geo olap from YT table to local CSV file
    """
    download.download_olap(yt, table, local_file)


@cli.command('download-polygons')
@click.option('--table', required=True)
@click.option('--local-file', required=True)
def download_polygons(table, local_file):
    """This should download polygon base table from YT to local CSV file
    """
    download.download_polygons(yt, table, local_file)


@cli.command('run-all')
@click.option('--in-geo-log-table', required=True)
@click.option('--out-polygon-base-table', required=True)
@click.option('--out-olap-table', required=True)
@click.pass_context
def run_all(ctx, in_geo_log_table, out_polygon_base_table, out_olap_table):
    """This should run whole  pipeline and produce OLAP table and GeoBase table.
    """
    with yt.TempTable() as tmp_yuid_to_socdem_table, \
         yt.TempTable() as tmp_yuid_to_geo_id_table:

        ctx.invoke(
            yuid_to_socdem,
            output_table=tmp_yuid_to_socdem_table,
        )
        ctx.invoke(
            latlon_to_geo_id,
            geo_log_table=in_geo_log_table,
            output_table=tmp_yuid_to_geo_id_table,
            resolution=9,
        )
        ctx.invoke(
            build_polygon_base,
            geo_id_table=tmp_yuid_to_geo_id_table,
            output_table=out_polygon_base_table,
        )
        ctx.invoke(
            build_olap,
            yuid_to_socdem_table=tmp_yuid_to_socdem_table,
            yuid_to_geo_id_table=tmp_yuid_to_geo_id_table,
            polygon_base_table=out_polygon_base_table,
            output_table=out_olap_table)


if __name__ == '__main__':
    yt.config.set_proxy('hahn')
    cli()
