text: # -*- coding: utf-8 -*-
  #BEGIN_HEADER
  import os
  import uuid
  import subprocess
  import shutil
  from KBaseReportPy.KBaseReportPyClient import KBaseReportPy as KBaseReport
  from biokbase.workspace.client import Workspace as workspaceService
  from ReadsUtils.ReadsUtilsClient import ReadsUtils
  from DataFileUtil.DataFileUtilClient import DataFileUtil
  #END_HEADER
  
  
  class jrb_fastqc:
      '''
      Module Name:
      jrb_fastqc
  
      Module Description:
      A KBase module: kb_fastqc
      '''
  
      ######## WARNING FOR GEVENT USERS ####### noqa
      # Since asynchronous IO can lead to methods - even the same method -
      # interrupting each other, you must be *very* careful when using global
      # state. A method could easily clobber the state set by another while
      # the latter method is running.
      ######################################### noqa
      VERSION = ""
      GIT_URL = ""
      GIT_COMMIT_HASH = ""
  
      #BEGIN_CLASS_HEADER
  
      def _get_input_file_ref_from_params(self, params):
          if 'input_file_ref' in params:
              return params['input_file_ref']
          else:
              if 'input_ws' not in params and 'input_file' not in params:
                  raise ValueError('Either the "input_file_ref" field or the ' +
                                   '"input_ws" with "input_file" fields ' +
                                   'must be set.')
              return str(params['input_ws']) + '/' + str(params['input_file'])
  
      def create_report(self, token, ws, uuid_string, read_file_path):
          output_html_files = list()
          output_zip_files = list()
          first_file = ""
          html_string = ""
          html_count = 0
          with open('/kb/data/index_start.txt', 'r') as start_file:
              html_string = start_file.read()
  
          # Make HTML folder
          html_folder = os.path.join(read_file_path, 'html')
          os.mkdir(html_folder)
          for file in os.listdir(read_file_path):
              label = ".".join(file.split(".")[1:])
              if(file.endswith(".zip")):
                  desc = 'Zip file generated by fastqc that contains ' + \
                         'original images seen in the report'
                  output_zip_files.append({'path': os.path.join(read_file_path, file),
                                           'name': file,
                                           'label': label,
                                           'description': desc})
              if(file.endswith(".html")):
                  # Move html into html folder
                  shutil.move(os.path.join(read_file_path,file),os.path.join(html_folder,file))
  
                  if(first_file == ""):
                      first_file = file
  
                  html_string+="            <button data-button=\"page "+str(html_count) + \
                               "\" data-page=\""+file+"\">Page "+str(html_count+1)+"</button>\n"
                  html_count += 1
  
          html_string += "        </div>    </div>    <div id=\"body\">\n"
          html_string += "        <iframe id=\"content\" "
          html_string += "style=\"width: 100%; border: none; \" src=\""+first_file+"\"></iframe>\n    </div>"
  
          with open('/kb/data/index_end.txt', 'r') as end_file:
              html_string += end_file.read()
  
          with open(os.path.join(html_folder, "index.html"), 'w') as index_file:
              index_file.write(html_string)
  
          shock = self.dfu.file_to_shock({'file_path': html_folder,
                                          'make_handle': 0,
                                          'pack': 'zip'})
          desc = 'HTML files generated by fastqc that contains report on ' + \
                 'quality of reads'
          output_html_files.append({'shock_id': shock['shock_id'],
                                    'name': 'index.html',
                                    'label': 'html files',
                                    'description': desc})
  
          report_params = {
              'direct_html_link_index': 0,
              'file_links': output_zip_files,
              'html_links': output_html_files,
              'workspace_name': ws,
              'report_object_name': 'kb_fastqc_report_' + uuid_string
          }
          kbase_report_client = KBaseReport(self.callback_url, token=token)
          output = kbase_report_client.create_extended_report(report_params)
          return output
      #END_CLASS_HEADER
  
      # config contains contents of config file in a hash or None if it couldn't
      # be found
      def __init__(self, config):
          #BEGIN_CONSTRUCTOR
          self.workspaceURL = config['workspace-url']
          self.scratch = os.path.abspath(config['scratch'])
          self.callback_url = os.environ['SDK_CALLBACK_URL']
          self.dfu = DataFileUtil(self.callback_url)
          #END_CONSTRUCTOR
          pass
  
  
      def runFastQC(self, ctx, input_params):
          """
          :param input_params: instance of type "FastQCParams" -> structure:
             parameter "input_ws" of String, parameter "input_file" of String,
             parameter "input_file_ref" of String
          :returns: instance of type "FastQCOutput" -> structure: parameter
             "report_name" of String, parameter "report_ref" of String
          """
          # ctx is the context object
          # return variables are: reported_output
          #BEGIN runFastQC
  
          token = ctx['token']
          wsClient = workspaceService(self.workspaceURL, token=token)
          uuid_string = str(uuid.uuid4())
          read_file_path = self.scratch+"/"+uuid_string
          os.mkdir(read_file_path)
  
          input_file_ref = self._get_input_file_ref_from_params(input_params)
  
          library=None
          try:
              library = wsClient.get_objects2({'objects': [{'ref': input_file_ref}]})['data'][0]
          except Exception as e:
              raise ValueError('Unable to get read library object from workspace: (' + input_file_ref + ')' + str(e))
  
          download_read_params = {'read_libraries': [], 'interleaved':"false"}
          if("SingleEnd" in library['info'][2] or "PairedEnd" in library['info'][2]):
              download_read_params['read_libraries'].append(library['info'][7]+"/"+library['info'][1])
          elif("SampleSet" in library['info'][2]):
              for sample_id in library['data']['sample_ids']:
                  if("/" in sample_id):
                      download_read_params['read_libraries'].append(sample_id)
                  else:
                      if(sample_id.isdigit()):
                          download_read_params['read_libraries'].append(library['info'][6]+"/"+sample_id)
                      else:
                          download_read_params['read_libraries'].append(library['info'][7]+"/"+sample_id)
  
          ru = ReadsUtils(os.environ['SDK_CALLBACK_URL'])
          ret = ru.download_reads(download_read_params)
  
          read_file_list = list()
          for file in ret['files']:
  
              obj_info = self.dfu.get_objects({'object_refs': [file]})['data'][0]['info']
              obj_name = obj_info[1]
              obj_ref_suffix = '_' + str(obj_info[6]) + '_' + str(obj_info[0]) + '_' + str(obj_info[4])
  
              files = ret['files'][file]['files']
  
              fwd_name = files['fwd'].split('/')[-1]
              fwd_name = fwd_name.replace('.gz', '')
              # using object_name + ref_suffix + suffix as file name
              fwd_name = obj_name + obj_ref_suffix + '.' + fwd_name.split('.', 1)[-1]
              shutil.move(files['fwd'], os.path.join(read_file_path, fwd_name))
              read_file_list.append(os.path.join(read_file_path, fwd_name))
  
              if(files['rev'] is not None):
                  rev_name = files['rev'].split('/')[-1]
                  rev_name = rev_name.replace('.gz', '')
                  rev_name = obj_name + obj_ref_suffix + '.' + rev_name.split('.', 1)[-1]
                  shutil.move(files['rev'], os.path.join(read_file_path, rev_name))
                  read_file_list.append(os.path.join(read_file_path, rev_name))
  
          subprocess.check_output(["fastqc"] + read_file_list)
          # report = "Command run: "+" ".join(["fastqc"]+read_file_list)
  
          output = self.create_report(token, input_params['input_ws'],
                                      uuid_string, read_file_path)
          reported_output = {'report_name': output['name'],
                             'report_ref': output['ref']}
  
          # Remove temp reads directory
          shutil.rmtree(read_file_path, ignore_errors=True)
  
          #END runFastQC
  
          # At some point might do deeper type checking...
          if not isinstance(reported_output, dict):
              raise ValueError('Method runFastQC return value ' +
                               'reported_output is not type dict as required.')
          # return the results
          return [reported_output]
      def status(self, ctx):
          #BEGIN_STATUS
          returnVal = {'state': "OK", 'message': "", 'version': self.VERSION,
                       'git_url': self.GIT_URL, 'git_commit_hash': self.GIT_COMMIT_HASH}
          #END_STATUS
          return [returnVal]
  