#!/usr/bin/env python
#
# Strelka - Small Variant Caller
# Copyright (c) 2009-2016 Illumina, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#

"""
This script configures the strelka pedigree small variant calling workflow
"""

import os,sys

scriptDir=os.path.abspath(os.path.dirname(__file__))
scriptName=os.path.basename(__file__)
workflowDir=os.path.abspath(os.path.join(scriptDir,"../lib/python"))
templateConfigDir=os.path.abspath(os.path.join(scriptDir,''))

sys.path.append(workflowDir)

from configBuildTimeInfo import workflowVersion
from strelkaSharedOptions import StrelkaSharedWorkflowOptionsBase
from configureUtil import BamSetChecker, groomBamList, OptParseException, joinFile
from makeRunScript import makeRunScript
from strelkaPedigreeWorkflow import StrelkaPedigreeWorkflow
from workflowUtil import ensureDir



class StrelkaPedigreeWorkflowOptions(StrelkaSharedWorkflowOptionsBase) :

    def workflowDescription(self) :
        return """Version: %s

This script configures Strelka pedigree small variant calling.
You must specify BAM or CRAM file(s) for the proband and additional related samples.
""" % (workflowVersion)


    def addWorkflowGroupOptions(self,group) :
        group.add_option("--probandAlignment", type="string",dest="probandBamList",metavar="FILE", action="append",
                         help="Proband BAM or CRAM file. [required] (no default)")
        group.add_option("--parentAlignment", type="string",dest="parentBamList",metavar="FILE", action="append",
                         help="BAM or CRAM file for a parent sample. (no default, submit argument one time for each parent)")
        group.add_option("--siblingAlignment", type="string",dest="siblingBamList",metavar="FILE", action="append",
                         help="BAM or CRAM file for a sibling sample. (no default, submit argument one time for each sibling)")
        group.add_option("--outputCallableRegions", dest="isOutputCallableRegions", action="store_true",
                         help="Output a bed file describing de-novo callable regions of the genome")

        StrelkaSharedWorkflowOptionsBase.addWorkflowGroupOptions(self,group)


    def getOptionDefaults(self) :

        self.configScriptDir=scriptDir
        defaults=StrelkaSharedWorkflowOptionsBase.getOptionDefaults(self)

        configDir=os.path.abspath(os.path.join(scriptDir,""))
        assert os.path.isdir(configDir)

        defaults.update({
            'runDir' : 'PedicureWorkflow',
            'isOutputCallableRegions' : False
            })
        return defaults



    def validateAndSanitizeExistingOptions(self,options) :

        StrelkaSharedWorkflowOptionsBase.validateAndSanitizeExistingOptions(self,options)
        groomBamList(options.probandBamList,"proband sample")
        groomBamList(options.parentBamList, "parent sample")
        groomBamList(options.siblingBamList, "sibling sample")



    def validateOptionExistence(self,options) :

        StrelkaSharedWorkflowOptionsBase.validateOptionExistence(self,options)


        if len(options.probandBamList) != 1 :
            raise OptParseException("Must specify one proband sample BAM/CRAM file")

        if len(options.parentBamList) != 2 :
            raise OptParseException("Must specify two parent sample BAM/CRAM files")

        bcheck = BamSetChecker()
        bcheck.appendBams(options.probandBamList,"proband")
        bcheck.appendBams(options.parentBamList,"parent")
        bcheck.appendBams(options.siblingBamList,"sibling",isAllowEmpty=True)
        bcheck.check(options.htsfileBin,
                     options.referenceFasta)

def main() :

    primarySectionName="strelkaPedigree"
    options,iniSections=StrelkaPedigreeWorkflowOptions().getRunOptions(primarySectionName,
                                                               version=workflowVersion)

    # we don't need to instantiate the workflow object during configuration,
    # but this is done here to trigger additional parameter validation:
    #
    StrelkaPedigreeWorkflow(options,iniSections)

    # generate runscript:
    #
    ensureDir(options.runDir)
    scriptFile=os.path.join(options.runDir,"runWorkflow.py")

    makeRunScript(scriptFile,os.path.join(workflowDir,"strelkaPedigreeWorkflow.py"),"StrelkaPedigreeWorkflow",primarySectionName,iniSections)

    notefp=sys.stdout
    notefp.write("""
Successfully created workflow run script.
To execute the workflow, run the following script and set appropriate options:

%s
""" % (scriptFile))


if __name__ == "__main__" :
    main()
