import os
import sys


# resource scopes for running via slurm
resource_scopes:
    gpus="local",
    threads='local',
    vcpu='global',
    mem_mb='local',
    disk_mb='local',
    time='local'




# configfile: can be multiply declared.
# They are read into the global 'config' variable dict
# Duplicate entries are over written based on priority,
#  see SMK docs for deets

# other config set via the config/day_profiles/[local|slurm] conf
configfile: f"config/global.yaml"

# biome no longer needed, but still referenced.  Remove this.
mg_biome=os.environ.get("DAY_BIOME",'AWSPC')
mg_profile=os.environ.get("DAY_PROFILE","na")
if mg_biome in ['na']:
    mg_biome = "AWSPC"

if mg_biome in ['na'] or mg_profile in ['na']:
    print("please run 'source dyoainit  --project <PROJECT> ; day-activate (profile);' ", file=sys.stderr )

# set work dir to the executing	dir ('..' from the Snakefile)
wd=os.path.abspath('.')
workdir: f"{wd}"


# TODO: This try block can be refactored away to a more clear
# config import set of statements.
try:
    ##
    ## If a bug with config appears around here and is inscrutibke, yamllint all of ther imported config files
    ##

    print(f"loading global: {wd}/config/global_{mg_biome}.yaml", file=sys.stderr)
    configfile: f"config/global_{mg_biome}.yaml"

    
    print(f"loading profile rule_config: {wd}/config/day_profiles/{mg_profile}/rule_config.yaml", file=sys.stderr)
    configfile: f"config/day_profiles/{mg_profile}/rule_config.yaml"

    if config['valid_biome'] in [mg_biome]:
        pass
    else:
        print(f"The profile {mg_profile} is only valid in the compute environment {config['valid_biome']}, you are running from {mg_biome}\n\n ----- && colr 'You shoudl probably abort'")

except Exception as e:
    print('MISSING DAY_BIOME OR DAY_PROFILE',e,  mg_biome)
    raise Exception(f"ERROR: {e}\n\n have you executed: 'source dyoainit  --project <PROJECT> ; dy-a (profilename)'?  is the profile activated valid for this environment? ")


# Import the global and help SMK files. The global and common SMK files
# contain shared methods used by other SMK files.

include: "rules/global_common.smk"  # Sample and supporting data includes are w/in global
include: "rules/help.smk"


# pizazzaz
day_init = """
                                                       
                                                       
   ______  _______ __   __        _____        __   __ 
   |     \ |_____|   \_/   |        |   |        \_/   
   |_____/ |     |    |    |_____ __|__ |_____    |    
                                                       
                                                       
|/////////////////////////////////////////////////////|
"""


##### SPECIAL RULES/DIRECTIVES: onstart, onsuccess, onerror
# ---------------------------------------------------------
# This block runs after the path through the dag has been calculated
# and before the first rule(s) begin processing.
# I initially put the calls to my staging work here, but then it occured tome
# this directive gets run at the start of every execution, including re-attempting
# a failed workflow.  And further, you can call on the workflow to only execute sections
# of the DAG, which might not even need the staged data.  So, that was all moved into rules
# where it feels a better fit... if a w/f has run past those nodes, and failed, when restarting
# those nodes are not run again.  And, I can add specific rule targets to force staging
# and force cleanup to test this stuff, as it's some of the most gnarly.  These could be useful
# for hitting an API to indicate you're starting.  Although, there is also a formal API spec
# snakemake had adopted which makes calls to an end point with workflow status updates, it even
# allows return communication to interrupt/stop/start the workflow.
# https://snakemake.readthedocs.io/en/stable/executing/monitoring.html#

# ON START
onstart:
    os.system('echo "$(date) $PWD _begin_" >> DYMEMBERS')

    if config["pizzazz"] in ["on"]        or random.randint(0, 9) in [1]:
        os.system("reset")
        print_colr_msg(  day_init,            "#FBC007",            "#100D07",            "b",            "0.1" )
        os.system("colr-run  -f bouncing_ball_rainbow -m '.' -- sleep 2 || sleep 1")


    msg = "               And we are off                  "
    wminm = get_term_width() - len(msg)
    tail = " " * wminm
    full = " " * int(get_term_width())
    msg2 = f"""{msg}{tail}"""
    if config["pizzazz"] in ["offX"]:
        print_colr_msg(            msg2,            os.environ.get('DY_WT0',"darkmagenta"),            os.environ.get('DY_WB0',"lawngreen"),            os.environ.get('DY_WS0','b'),       '2' )

    # If a jira ticketID is set at the command line with --config jid=RT-1000, the ticket will be updated at start, and fail/success
    if config["jid"] != "":
        targets = "xxxxx"
        nsamps = len(samples)
        details = "."
        targets = "test"
        url = os.popen("echo $PWD").readline().rstrip()
        c1 = "FF0AFB"
        c2 = "828DED"
        c3 = "EEE7EE"
        update_jira(
	config["jid"],
	targets,
	nsamps,
	details,
	url,
	c1,
	c3,
	c3,
	samples.EX[0],
	samples.RU[0],
	"starting" )

# ON SUCCESS
onsuccess:
    nsamps_pass = "na"  # Calculate this at some point
    nsamps_fail = "na"  # and this
    os.system(
        'echo "$(date) $PWD COMPLETE, pass:'
        + nsamps_pass
        + ", fail:"
        + nsamps_fail
        + '" >> DYMEMBERS'
    )
    if "lock_analysis_dirs" in config:
        print( "\n\n\t [[ INFO ]] ALL Directories Are Now Read Only. \n\n", file=sys.stderr)
        os.system("chmod -R +r-w ./* ;")
    else:
        print("\n\n\tWARNING!!!! ALL Directories Are Remaining Unlocked.   To have Directories Lock Automatically upon successfull completion, set --lock-analysis-dirs when calling day-run.\n\n",
            file=sys.stderr)

    msg = "]]]]--------WORKFLOW SUCCESS====================]]]]]--"
    wminm = get_term_width() - len(msg)
    full = " " * int(get_term_width())
    tail = "-" * wminm
    msg2 = f"""{full}\n{msg}{tail}"""


    if config["pizzazz"] in ["on","off"]:
        print_colr_msg(
            msg2,
            "black",
            "hotpink",
            "b",
            1.2        )

    # If a jira ticketID is set at the command line with --config jid=RT-1000, the ticket will be updated at start, and fail/success
    if config["jid"] != "":
        targets = "xxxxx"
        nsamps = len(samples)
        details = "."
        targets = "test"
        url = os.popen("echo $PWD").readline().rstrip()
        c1 = "23FF0A"
        c2 = "00E038"
        c3 = "ADFFD3"
        update_jira(
            config["jid"],
            targets,
            nsamps,
            details,
            url,
            c1,
            c3,
            c3,
            samples.EX[0],
            samples.RU[0],
            "success" )

    #os.system(f"rm -rf /fsx/scratch/{config['tmpsub']} &")
    os._exit(0)


# ON ERROR
onerror:
    os.system('echo "$(date) $PWD FAIL" >> DYMEMBERS')
    msg = "        Womp Womp.  something went awry---- "
    wminm = get_term_width() - len(msg)
    tail = " " * wminm
    full = " " * int(get_term_width())
    msg2 = f"""{full}\n{msg}{tail}"""
    if config["pizzazz"] in ["on", "off"]:
        print_colr_msg(
            msg2,
            os.environ.get('DY_ET0',"firebrick3"),
            os.environ.get('DY_EB0',"midnightblue"),
            os.environ.get('DY_ES0',"f"),
            config["warn_err_sleep"])
    # If a jira ticketID is set at the command line with --config jid=RT-1000, the ticket will be updated at start, and fail/success
    if config["jid"] != "":
        targets = "xxxxx"
        nsamps = len(samples)
        details = "."
        targets = "test"
        url = os.popen("echo $PWD").readline().rstrip()
        c1 = "FF4B3E"
        c2 = "FAB79E"
        c3 = "E8ECEE"
        update_jira(
            config["jid"],
            targets,
            nsamps,
            details,
            url,
            c1,
            c3,
            c3,
            samples.EX[0],
            samples.RU[0],
            "error")

    # If SMK exits ungracefully, a TON of /fsx/scratch files may be left to cleanup.
    #os.system(f"rm -rf /fsx/scratch/{config['tmpsub']} &")
    os._exit(1)


# #### IMPORT ALL OF THE RULES
# --------------------------
include: "rules/alignstats.smk"
include: "rules/alignstats_compile.smk"
include: "rules/art.smk"
include: "rules/bcftools_vcfstat.smk"
include: "rules/bwa_mem2a_align_sort.smk"
include: "rules/calc_coverage_eveness.smk"
include: "rules/calc_coverage_evenness_two.smk"
include: "rules/clair3.smk"
include: "rules/cyp2d6_cyrius.smk"
include: "rules/deepvariant_1_5.smk"
include: "rules/deepvariant_1_9.smk"
include: "rules/deepvariant_1_9_roche.smk"
include: "rules/deepvariant_ug.smk"
include: "rules/deepsomatic.smk"
include: "rules/mutect2.smk"
include: "rules/doppel_mrkdups.smk"
include: "rules/no_dedup.smk"
include: "rules/no_dedup_cram.smk"
include: "rules/duphold.smk"
include: "rules/dysgu_sv.smk"
include: "rules/expansionhunter.smk"
include: "rules/fastqc.smk"
include: "rules/fastv.smk"
include: "rules/legacy_cram_compat_bam.smk"
include: "rules/gatk_contam.smk"
# include: "rules/gba_gauchian.smk"
include: "rules/smn_copynumbercaller.smk"
include: "rules/generate_deduplicated_bams.smk"
include: "rules/go_left.smk"
# include: "rules/hisat2.smk"
# KAT is disabled at the workflow import level. It is too slow/noisy for routine
# service and should not be pulled into any active target until explicitly
# revalidated.
# include: "rules/kat.smk"
include: "rules/seqfu.smk"
include: "rules/lofreq2.smk"
include: "rules/aivariant.smk"
include: "rules/varnet.smk"
include: "rules/manta.smk"
include: "rules/merge_all_bams.smk"
include: "rules/mosdepth.smk"
include: "rules/quickmer2.smk"
include: "rules/multiqc_cov_aln.smk"
include: "rules/multiqc_final_wgs.smk"
include: "rules/multiqc_singleton.smk"
include: "rules/multiqc_for_raw_fastqs.smk"
include: "rules/octopus.smk"
include: "rules/peddy.smk"
# Picard is disabled at the workflow import level. Current Picard/htsjdk cannot
# read the CRAM 3.1 outputs produced by the short-read path reliably.
# include: "rules/picard.smk"
include: "rules/prep_input_sample_files.smk"
include: "rules/bclconvert.smk"
# Qualimap is disabled at the workflow import level. The current Qualimap build
# is too slow and unreliable for routine service on these short-read CRAM/BAMs.
# include: "rules/qualimap.smk"
include: "rules/rtg_vcfeval.smk"
include: "rules/rtg_vcfstats.smk"
include: "rules/run_qc_reports.smk"
include: "rules/samtools_metrics.smk"
include: "rules/sent_DNAscope.smk"
include: "rules/sent_DNAscope_cgt7p.smk"
include: "rules/sent_TNscope.smk"
include: "rules/sentieon.smk"
include: "rules/sent_aln_sort_snv.smk"
include: "rules/sentieon_pangenome_shortreads.smk"
include: "rules/sentieon_pangenome_ug.smk"
include: "rules/sent_snv_ug.smk"
include: "rules/sent_snv_pb.smk"
include: "rules/roche_sbxd.smk"
include: "rules/sent_snv_ont.smk"
include: "rules/hyb_ensemble_multi_platform.smk"
include: "rules/sent_hybrid_ilmn_ont.smk"
include: "rules/sent_hybrid_ug_ont.smk"
include: "rules/sent_hybrid_ilmn_ont_modular.smk"
include: "rules/sent_hybrid_ilmn_ont_modular.refactored.smk"
include: "rules/sent_hybrid_ilmn_pb_modular.refactored.smk"
include: "rules/sent_hybrid_ug_ont_modular.refactored.smk"
include: "rules/sent_hybrid_ug_pb_modular.refactored.smk"
include: "rules/sent_hybrid_ug_ont_modular.smk"
include: "rules/sent_hybrid_ilmn_pb.smk"
include: "rules/sent_hybrid_ug_pb.smk"
include: "rules/sent_hybrid_ilmn_pb_modular.smk"
include: "rules/sent_hybrid_ug_pb_modular.smk"
include: "rules/sent_hybrid_roche_ont_modular.smk"
include: "rules/sent_hybrid_roche_pb_modular.smk"
include: "rules/sentieon_gatk.smk"
include: "rules/sentieon_new_gatk.smk"
include: "rules/sentieon_markdups.smk"
include: "rules/site_mix_contam.smk"
include: "rules/relatedness_batch.smk"
include: "rules/sentmm2_align_sort.smk"
include: "rules/sentmm2ont_align_sort.smk"
include: "rules/gauchian.smk"
include: "rules/parascopy.smk"
include: "rules/smaca.smk"
include: "rules/genetocn.smk"
include: "rules/htd_calls.smk"
# SnpEff is disabled at the workflow import level. Its rule is intentionally
# unavailable until the annotation integration is revalidated.
# include: "rules/snpeff.smk"
include: "rules/strobe_align_sort.smk"
# Stargazer is intentionally excluded from htd_callers until its stale rule is repaired.
# include: "rules/stargazer.smk"
include: "rules/tiddit.smk"
include: "rules/truvari_sv_benchmark.smk"
include: "rules/surveyor.smk"
include: "rules/unmapped_metagenomics.smk"
include: "rules/vpot.smk"
include: "rules/vep.smk"
include: "rules/verifybamid2_contam.smk"
include: "rules/workflow_target_aliases.smk"
include: "rules/workflow_staging.smk"


# #### A FEW FUSSY THINGS
# ----------------------
# Snakemake does not like double '/'s in any path
# Snakemake also prefers no leading ./ to local paths

# #### RULES- SPECIFICALLY 'all' (replaced by day here)
# 'all' is the widely adopted name of the rule which run the full pipeline.
# As daylily is not a single pipeline, the targets which produce
# viable results are annotated with TARGET and may be found by running
# 'dy-r help' or 'dy-r <TAB><TAB>', the second tab completing valid targets.


# localrules: defines a comma sep list of rule names to run on the headnode.
# Generally useful for super-low compute rules which don't need to be farmed
# out to a compute node to run. Use with care!

localrules:
    day,  # Instructs snakemake not to schedule this as a distributed job, but run locally on the executing host.


rule day:  # TARGET : Synonym for all
    "Does nothing but touch the output file. To run a useful rule run 'dy-r <TAB>'"
    output:
        "logs/day.completed",
    shell:
        "touch {output};"

rule all:  # TARGET : Prompt user to run help
    shell:
        """
        echo 'Hello!  To learn how to run daylily, execute the following:' ;
	echo ' ';
        echo ' ';
        echo 'source dyoainit  --project <PROJECT> ';
        echo 'dy-a local/slurm';
        echo 'dy-r help';
        """


# #### AND THAT IS THE SNAKEFILE
# ------------------------------
 
