#!python3

# Command line tool for manipulating the yaml files in COVID-19 spectrum monitoring data

import sys
sys.path.insert(0,'.')

import click
from pathlib import Path
from numbers import Number
# import shutil
import labbench as lb
lb._force_full_traceback(True)
import labbench as lb
import importlib

# the Rack metaclass is where the configs live
rack_factory = type(lb.Rack)

@click.group(help="configure and run labbench Rack objects")
def cli():
    pass


@cli.command(
    name='init',
    help="""Start a new configuration directory for a labbench Rack.
    
    Do "from <module> import <class-name>", and introspect on the class
    to autogenerate template configuration files. The configuration
    output is a new directory specified by CONFIG-DIR. There must be no
    existing file or directory in this path. Python imports follow the context of the
    current working directory and PYTHONPATH as normal."""
)
@click.argument('import_str', type=str)#, help='name of the rack class to import, e.g., "modulename.MyRack"')
@click.argument('config-dir', type=click.Path(exists=False))#, help='path to the output directory')
@click.option('--force', is_flag=True, help='overwrite pre-existing files')
@click.option('--with-defaults', is_flag=True, help='include sequence parameters that have defaults')
def init(import_str, config_dir, force=False, with_defaults=False):
    if '.' in import_str:
        import_str, class_name = import_str.rsplit('.', 1)
    else:
        class_name = None
    
    cls = lb._rack.import_as_rack(import_str, class_name)
    obj = cls()

    lb.dump_rack(obj, config_dir, exist_ok=force, with_defaults=with_defaults)


@cli.command(
    name='reset',
    help=f"""Replace an existing sequence table csv file with a header stub.

    The csv output contains a single row specifying column headers of the 
    sequence. To determine the expanded variables to run, the Rack class is imported
    from the csv's parent directory, run from the context
    of the current working directory and PYTHONPATH."""
)
@click.argument('csv_path', type=click.Path(exists=True))#, help='path to the config directory')
@click.option('--with-defaults', is_flag=True, help='include sequence parameters that have defaults')
def rewrite(csv_path, sequence_name, with_defaults=False):

    # pull in the rack
    rack = lb.load_rack(csv_path.parent, apply=True)

    # make_sequence_stub takes care of the introspection on the rack
    lb._serialize.make_sequence_stub(rack, csv_path.stem, csv_path.parent, with_defaults=with_defaults)

@cli.command(
    name='run',
    help="""Step through calls to a Rack sequence defined in a CSV table.

    The parent directory of the csv file needs to have a config.yaml as generated by the
    `init` command. The rack class is imported from the csv's parent directory, run from
    the context of the current working directory and PYTHONPATH."""
)
@click.argument('csv_path', type=click.Path(exists=True))#, help='path to the config directory')
def run(csv_path, sequence_name):
    config_dir = csv_path.parent
    sequence_name = csv_path.stem

    # instantiate a Rack from config.yaml
    rack = lb.load_rack(config_dir, apply=True)

    # get the callable bound sequence before connection
    # in case it does not exist
    bound_seq = getattr(rack, sequence_name)

    # instantiate the rack, binding the Sequence method
    with rack:
        # ...and run the sequence object
        
        print(dir(bound_seq))
        bound_seq.iterate_from_csv(csv_path)


if __name__ == '__main__':
    cli()
