from os import listdir, makedirs
from os.path import exists, join
import shutil

from flask import current_app
from flask.cli import with_appcontext
import click
import iatikit

from ..core import models
from . import utils


@click.group('iati')
def iati_cli():
    """Automated test commands."""
    pass


@iati_cli.command('download')
@with_appcontext
def download_iati_data():
    '''Fetch the relevant data from the IATI registry.'''

    if models.Organisation.query.count() == 0:
        click.secho('Error: No organisations to fetch data for.', fg='red')
        click.echo('Perhaps you need to import some, using:')
        click.echo('\n    $ flask setup orgs\n')
        raise click.Abort()

    click.echo('Fetching a snapshot of *all* data from the IATI registry ...')
    iatikit.download.data()
    updated_on = iatikit.data().last_updated.date()

    input_path = iatikit.data().path
    output_path = join(current_app.config.get('IATI_DATA_PATH'), str(updated_on))

    click.echo('Copying files into place ...')
    click.echo(f'Output path: {output_path}')

    if exists(output_path):
        click.secho('Error: Output path exists.', fg='red')
        raise click.Abort()
    makedirs(output_path)

    shutil.copy(join(input_path, 'metadata.json'),
                join(output_path, 'metadata.json'))

    for organisation in models.Organisation.query:
        if not organisation.registry_slug:
            # if the org isn’t an IATI publisher, skip
            continue
        # Copy data files into place
        shutil.copytree(join(input_path, 'data', organisation.registry_slug),
                        join(output_path, 'data', organisation.slug))
        # Copy metadata files into place
        shutil.copytree(join(input_path, 'metadata', organisation.registry_slug),
                        join(output_path, 'metadata', organisation.slug))


@iati_cli.command('test')
@click.option('--date', default='latest', help='Date of the data to test, in ' +
                                               'YYYY-MM-DD. Defaults to ' +
                                               'most recent.')
@with_appcontext
def run_iati_tests(date):
    '''Test a set of downloaded IATI data.'''

    click.echo('Loading tests ...')
    all_tests = utils.load_tests()

    iati_data_path = current_app.config.get('IATI_DATA_PATH')
    iati_result_path = current_app.config.get('IATI_RESULT_PATH')
    try:
        snapshot_dates = listdir(join(iati_data_path))
        if snapshot_dates == []:
            raise FileNotFoundError

        if date == 'latest':
            snapshot_date = max(snapshot_dates)
        else:
            if not exists(join(iati_data_path, date)):
                raise ValueError
            snapshot_date = date
    except FileNotFoundError:
        click.secho('Error: No IATI data to test.', fg='red')
        click.echo('Perhaps you need to download some, using:')
        click.echo('\n    $ flask iati download\n')
        raise click.Abort()
    except ValueError:
        click.secho(f'Error: No IATI data found for given date ({date}).', fg='red')
        raise click.Abort()

    click.echo(f'Testing IATI data snapshot ({snapshot_date}) ...')
    data_path = join(iati_data_path, snapshot_date)
    output_path = join(iati_result_path, snapshot_date)

    publishers = iatikit.data(path=data_path).publishers
    for publisher in publishers:
        org = models.Organisation.where(slug=publisher.name).first()
        click.echo(f'Testing organisation: {org.name} ({org.slug}) ...')
        path = join(output_path, org.slug)
        makedirs(path, exist_ok=True)
        for test in all_tests:
            fname = join(path, utils.slugify(test.name) + '.csv')
            click.echo(f'  {test} ...')
            summary = utils.run_test(test, publisher, fname,
                                     today=snapshot_date)
            click.echo(f'  {summary}')

@@ -1314,24 +1314,104 @@
 ta.json'))%0A%0A
+    with click.progressbar(models.Organisation.all()) as all_organisations:%0A    
     for orga
@@ -1422,24 +1422,21 @@
 tion in 
-models.O
+all_o
 rganisat
@@ -1442,24 +1442,22 @@
 tion
-.query:%0A
+s:%0A   
         
 if n
@@ -1448,24 +1448,25 @@
 %0A           
+ 
 if not organ
@@ -1488,16 +1488,20 @@
 y_slug:%0A
+    
         
@@ -1547,16 +1547,20 @@
 r, skip%0A
+    
         
@@ -1576,24 +1576,28 @@
 nue%0A        
+    
 # Copy data 
@@ -1605,32 +1605,36 @@
 iles into place%0A
+    
         shutil.c
@@ -1711,32 +1711,36 @@
                 
+    
 join(output_path
@@ -1769,16 +1769,20 @@
 .slug))%0A
+    
         
@@ -1814,32 +1814,36 @@
 o place%0A        
+    
 shutil.copytree(
@@ -1892,32 +1892,36 @@
 registry_slug),%0A
+    
                 

Add an annoying progress bar