from maps.wikimap.stat.report_tools.report_data_copy.lib import report_data_copy

import statface_client

from datetime import datetime, date, timedelta
import argparse
import dateutil.parser
import json


def tomorrow():
    return datetime.combine(
        date.today() + timedelta(days=1),
        datetime.min.time()
    )


def parse_args():
    parser = argparse.ArgumentParser(
        description='Copies data from one Yandex.Stat report to another and adds new dimensions if needed.'
    )
    parser.add_argument(
        '--env',
        help='Yandex.Stat version to use: %(choices)s (default: %(default)s)',
        choices=['beta', 'production'],
        default='beta',
        metavar='ENV'
    )
    parser.add_argument(
        '--src',
        help='source report',
        required=True
    )
    parser.add_argument(
        '--dest',
        help='destination report',
        required=True
    )
    parser.add_argument(
        '--scale',
        help='scale to copy: %(choices)s',
        required=True,
        choices=['continual', 'minutely', 'hourly', 'daily', 'weekly', 'monthly', 'quarterly', 'yearly'],
        metavar='SCALE'
    )
    parser.add_argument(
        '--new',
        help='new dimensions with their default values to be added into the destination report '
             'in form of a dict: \'{"dimension":"default_value", ...}\'',
        default=dict(),
        type=json.loads
    )
    parser.add_argument(
        '--new-tree',
        help='new tree dimensions with their default values to be added into the destination report '
             'in form of a dict: \'{"dimension":"default_value", ...}\'',
        default=dict(),
        type=json.loads
    )
    parser.add_argument(
        '--rename',
        help='dimensions to rename (before adding new ones, if they are specified) '
             'in form of a dict: \'{"old_name":"new_name", ...}\'',
        default=dict(),
        type=json.loads
    )
    parser.add_argument(
        '--min-date',
        help='minimum date to copy report (default: "%(default)s")',
        default='1970-01-01 00:00:00',
        type=dateutil.parser.parse
    )
    parser.add_argument(
        '--max-date',
        help='maximum date to copy report (default: "%(default)s")',
        default=tomorrow(),
        type=dateutil.parser.parse
    )
    parser.add_argument(
        '--download-batch',
        help='download data by batches of this size (days, default: %(default)s)',
        type=int,
        default=7
    )
    parser.add_argument(
        '--upload-batch',
        help='upload data by batches of this size (rows, default: %(default)s)',
        type=int,
        default=40000
    )
    parser.add_argument(
        '--download-tree-max-distance',
        help='download tree dimensions up to this distance (default: %(default)s)',
        type=int,
        default=9000   # https://wiki.yandex-team.ru/statbox/Statface/externalreports/#derevja
    )
    return parser.parse_args()


def create_statface_client(env):
    if env == 'production':
        return statface_client.ProductionStatfaceClient()
    else:
        return statface_client.BetaStatfaceClient()


def create_report(sf_client, name):
    try:
        return sf_client.get_report(name)
    except statface_client.errors.StatfaceInvalidReportPathError:
        print(f"Report '{name}' does not exist.")
        exit(1)                 # @todo use name


def main():
    args = parse_args()
    sf_client = create_statface_client(args.env)
    src_report = create_report(sf_client, args.src)
    dst_report = create_report(sf_client, args.dest)

    print(f"Copy data from '{args.src}\' to \'{args.dest}\'")

    if len(args.new):
        print("Following dimensions will be added:")
        for dim, default_value in args.new.items():
            print(f"Copy data from '{args.src}\' to \'{args.dest}\'")

    if len(args.new_tree):
        print("Following tree dimensions will be added:")
        for dim, default_value in args.new_tree.items():
            print(f"- '{dim}', default value: '{default_value}'")

    if len(args.rename):
        print("Following dimensions will be renamed:")
        for old_name, new_name in args.rename.items():
            print(f"- '{old_name}' -> '{new_name}'")

    report_data_copy.copy_report(
        src_report,
        dst_report,
        args.download_batch,
        args.upload_batch,
        args.min_date,
        args.max_date,
        args.scale,
        args.download_tree_max_distance,
        args.new,
        args.new_tree,
        args.rename,
    )
