#!/usr/bin/env python

"""
Step 8
======
In this step, we'll do everything from steps 1 through 7 - then,
when the workflow finishes, we'll check a particular dataset by name
for statistics on how the workflow did.

The output will be in a new history named 'Step 8'.
"""
import os
import sys
import pprint
import time

import users_1
import histories_3
import tools_1
import hdas_2
import workflows_1

# we'll be using the get_dataset_column function from this to get the statistics
import datasets_3

NEW_HISTORY_NAME = 'Step 8'
DATA_TO_UPLOAD = 'data/myIlluminaRun.solexa.fastq'

SOLEXA_QC_WORKFLOW_NAME = 'Joined Solexa QC'
SOLEXA_QC_WORKFLOW_INPUT_STEP = 6

# here's the name of the dataset containing the statistics - kinda silly in this case
STATISTICS_DATASET_NAME = 'statistics'
STATISTICS_DATASET_COLUMN = 5

# ----------------------------------------------------------------------------- main
if __name__ == '__main__':
    try:
        # check the connection
        users = users_1.get_users()

        # create a new history
        new_history = histories_3.create_history( NEW_HISTORY_NAME )
        print 'created history!', new_history[ 'name' ]
        new_history_id = new_history[ 'id' ]
        new_history_details = histories_3.get_history( new_history_id )

        # upload a file
        tool_output_datasets = tools_1.upload_hda( new_history_id, DATA_TO_UPLOAD )
        uploaded_file_data = tool_output_datasets[ 'outputs' ][0]
        print 'uploaded hda!', uploaded_file_data[ 'name' ]
        uploaded_file_id = uploaded_file_data[ 'id' ]

        # and use get_hda to get details on the new, uploaded HDA
        uploaded_hda_details = hdas_2.get_hda( new_history_id, uploaded_file_id )
        uploaded_hda_state = uploaded_hda_details[ 'state' ]

        # wait for the upload to finish
        while uploaded_hda_state != 'ok':
            print '\t uploaded_hda_state:', uploaded_hda_state
            print '\t (waiting 4 seconds...)'
            time.sleep( 4.0 )

            # keep checking to get any new state the HDA might move into
            uploaded_hda_details = hdas_2.get_hda( new_history_id, uploaded_file_id )
            uploaded_hda_state = uploaded_hda_details[ 'state' ]

        # here's the new stuff...moving fast now

        # get the info of the all workflows available to us
        all_workflows = workflows_1.get_workflows()

        # let's search that info for the name of the one we want in the list of all workflows
        found_workflow = None
        for workflow in all_workflows:
            if workflow[ 'name' ] == SOLEXA_QC_WORKFLOW_NAME:
                found_workflow = workflow

        if not found_workflow:
            raise Exception( 'If you see this error, let one of the workhop presenters know' )

        print 'found workflow!', found_workflow[ 'name' ]
        target_workflow_id = found_workflow[ 'id' ]
        target_workflow_details = workflows_1.get_workflow( target_workflow_id )

        # now we'll run it:
        print 'running',  found_workflow[ 'name' ], 'workflow...'
        workflow_output = workflows_1.run_single_input_workflow_on_hda( target_workflow_id,
            new_history_id, uploaded_file_id, SOLEXA_QC_WORKFLOW_INPUT_STEP )
        print 'workflow started!'

        # the 'outputs' list of the workflow_output dictionary are the ids of the HDAs the workflow creates
        output_hda_ids = workflow_output[ 'outputs' ]

        # wait for them all to finish
        for hda_id in output_hda_ids:
            workflow_hda_details = hdas_2.get_hda( new_history_id, hda_id )
            workflow_hda_state = workflow_hda_details[ 'state' ]
            workflow_hda_name = workflow_hda_details[ 'name' ]
            print workflow_hda_name

            while workflow_hda_state != 'ok':
                print '\t state:', workflow_hda_state
                print '\t (waiting 4 seconds...)'
                time.sleep( 4.0 )

                # keep checking to get any new state the HDA might move into
                workflow_hda_details = hdas_2.get_hda( new_history_id, hda_id )
                workflow_hda_state = workflow_hda_details[ 'state' ]

            print '\t ok'
        print 'workflow complete!'

        # get some statistics using the datasets api
        # we'll need to find the proper HDA using it's name - we can use the same pattern we used to find the workflow
        found_statistics = None
        hda_summaries = hdas_2.get_hdas( new_history_id )
        for hda_summary in hda_summaries:
            if hda_summary[ 'name' ] == STATISTICS_DATASET_NAME:
                found_statistics = hda_summary
                # (we can use 'break' to exit the loop early)
                break
        if not found_statistics:
            raise Exception( 'If you see this error, let one of the workhop presenters know' )
        statistics_dataset_id = found_statistics[ 'id' ]

        # now we'll use the datasets API to get some actual data from *inside* the dataset's file
        # in this case, we're interested in column 5 - the per base quality score across all the reads
        column_data = datasets_3.get_dataset_column( statistics_dataset_id, STATISTICS_DATASET_COLUMN )
        # get_dataset_column produces both raw data (in 'data') and some rough statistics of its own
        #   we'll grab the mean and median per-base quality for this fastq
        # there will be metadata for each column - but we only got one column so we'll get the first metadata object
        column_metadata = column_data[ 'meta' ][0]
        mean_perbase_quality = column_metadata[ 'mean' ]
        median_perbase_quality = column_metadata[ 'median' ]

        # now we can do itelligent things based on the stats:
        #   - like add the fastq to a library or request a re-run of the sequencing (and make the lab techs mad)
        
    except Exception, exc:
        print 'Error getting statistics from dataset:', str( exc )
        sys.exit( 1 )

    print 'mean:', mean_perbase_quality, 'median:', median_perbase_quality
