import click
import json
import os
import time
from saas.library.python.ferryman import Ferryman, FerrymanBatchWaiter


@click.group()
@click.option('--host', help='Ferryman base url', required=False, default="")
@click.option('--service', help='SaaS service name', required=False, default="")
@click.option('--ctype', help='SaaS service ctype', required=False, default="")
@click.pass_context
def cli(context, host, service, ctype):
    if not (host or service and ctype):
        raise Exception("Error: Options host or service and ctype must be set")
    context.ensure_object(dict)
    context.obj['client'] = Ferryman(fqdn=host) if host else Ferryman.from_saas_service(service_name=service, service_ctype=ctype)


def with_client(func):

    @click.pass_context
    def wrapper(context, *args, **kwargs):
        client = context.obj['client']
        return func(client, *args, **kwargs)

    return wrapper


@cli.command('add-table')
@click.option('--table', required=True)
@click.option('--cluster', default=None, required=False)
@click.option('--timestamp', required=True, default=int(time.time() * 1000 * 1000), type=int)
@click.option('--namespace', default=None)
@click.option('--delta', is_flag=True)
@click.option('--format', 'format_', type=click.Choice(['json', 'message', 'simple', 'personal', 'geo_yt'], case_sensitive=True), default='json')
@with_client
def add_table(ferryman: Ferryman, table: str, cluster: str, timestamp: int, namespace: str, delta: bool, format_: str):
    # nirvana interface: file with json description of table
    if os.path.exists(table):
        with open(table) as f:
            table = json.load(f)['table']
    res = ferryman.api.add_table(
        path=table,
        timestamp=timestamp,
        is_delta=delta,
        namespace=namespace,
        format_=format_,
        cluster=cluster
    )
    print_result(res)


@cli.command('pause-cooking')
def pause_cooking(ferryman: Ferryman):
    ferryman.api.pause_cooking()


@cli.command('resume-cooking')
def resume_cooking(ferryman: Ferryman):
    ferryman.api.resume_cooking()


@cli.command('add-full-table')
@click.option('--tables', required=True)
@click.option('--format', 'format_', type=click.Choice(['json', 'message', 'simple', 'personal', 'geo_yt'], case_sensitive=True), default='json')
def add_full_tables(ferryman: Ferryman, tables: str):
    res = ferryman.api.add_full_tables(tables=tables)
    print_result(res)


@cli.command('get-all-timestamps')
@with_client
def get_all_timestamps(ferryman: Ferryman):
    print_result(ferryman.api.get_all_timestamps())


@cli.command('get-namespaces')
@with_client
def get_namespaces(ferryman: Ferryman):
    print_result(ferryman.api.get_namespaces())


@cli.command('get-states')
@click.option('--num-states', required=True)
@with_client
def get_states(ferryman: Ferryman, num_states):
    print_result(ferryman.api.get_states(num_states))


@cli.command('get-batch-status')
@click.option('--batch', type=int)
@with_client
def get_batch_status(ferryman: Ferryman, batch):
    print_result(ferryman.api.get_batch_status(batch))


@cli.command('wait-batch-status')
@click.option('--status', required=True)
@click.option('--batch', type=int, required=True)
@click.option('--max-wait-minutes', type=int, required=True)
@with_client
def wait_batch_status(ferryman: Ferryman, status, batch, max_wait_minutes):
    print_result(FerrymanBatchWaiter(ferryman=ferryman, batch_id=batch, max_minutes_in_same_state=max_wait_minutes).wait_batch_status(desired_states=[status]))


def print_result(result):
    if result is not None:
        print(json.dumps(result))


def main():
    cli()


if __name__ == '__main__':
    main()
