from falcon_kit.pype import Dist
#from falcon_kit import pype_tasks
from falcon_kit.pype import (wrap_gen_task as gen_task, gen_parallel_tasks, Dist)
from .. import io
from . import top
import glob
import logging
import os

LOG = logging.getLogger(__name__)

TASK_GATHER_POLISH="""
python3 -m falcon_unzip.mains.polish_gather --all-ctgs-json {input.FNS} --p-ctg-fn polished_p_ctgs.fasta --h-ctg-fn polished_h_ctgs.fasta
samtools faidx {output.FP}
samtools faidx {output.FH}
"""

TASK_POLISH="""
# Get the sequences (primary/haplotig) to polish
samtools faidx {input.FA} {params.ctg} > ref.fasta

# Get reads that are assigned to the (primary/haplotig) either by phasing or by
# mapping.
perl -lane 'print $F[0] if $F[1] eq "{params.ctg}"' {input.READTOCTG} | sort | uniq > readnames.txt

# Get the read sequences that are assigned to the (primary/haplotig)
samtools fqidx -r readnames.txt {input.FQ} > reads.fastq

time pbmm2 align --sort -j {params.pypeflow_nproc} --preset CCS ref.fasta reads.fastq | samtools view -q 5 -bh > aligned.bam
time falconc bam-filter-clipped -t -F 0x704 --input-fn:- --output-fn aln.sam --output-count-fn filtered_aln_count.txt < aligned.bam

#filtered_aln_count.txt is generated by `falconc bam-filter-clipped`
is_good=$(cat filtered_aln_count.txt)
if [ ${{is_good}} -eq "0" ]; then
    # There are no records in the BAM file. Create an empty output file.
    touch {output.POL}
else
    time racon -t {params.pypeflow_nproc} reads.fastq aln.sam ref.fasta > {output.POL}
fi

# Cleanup
rm -f *.bam *.sam *.fastq
"""

TASK_GATHER_UNPHASED="""
find {input.ctg*} > bam_list.txt
samtools merge -b bam_list.txt tmp.bam
samtools sort -o {output.UBAM} tmp.bam
samtools index {output.UBAM}
falconc falcon-read2ctg-augment --phase-fn {input.READTOCTG} --bam-fn {output.UBAM} --out-fn {output.READTOCTG_AUG}
"""

TASK_PLACE_UNPHASED="""
python3 -m falcon_unzip.mains.polish_unphased_readmapping --ctg {params.ctg} --fai {input.fai} --out-read-names read_names.txt --out-ref-names ref_names.txt --read-to-ctg {input.readtoctg}
samtools fqidx -r read_names.txt {input.fq} > reads.fastq
samtools faidx -r ref_names.txt {input.fa}  > ref.fasta
pbmm2 align -j 1 --preset CCS --sort ref.fasta reads.fastq > tmp.bam
falconc bam-filter-clipped -t -F 0x704 --output-count-fn filtered_aln_count.txt --input-fn:- --output-fn:- < tmp.bam | samtools view -q 5 -bh > aln.bam
"""

TASK_POLISH_PREAMBLE="""
cat {input.P} {input.H} > {output.COMBINED}
samtools faidx {output.COMBINED}
cat ../../3-unzip/2-htigs/chunk_*/uow-*/*ctg_edges* > {output.EDGES}
python3 -m falcon_unzip.mains.polish_read_to_ctg --rid-to-phase-fn {input.RIDTOPHASE} --edges-fn {output.EDGES} --lookup-fn {input.READNAMELOOKUP} --out {output.READTOCTG}

# Assume FQ is external. (TODO: Use a program so we can be more lenient.)
ln -sf {input.FQ} {output.FQO}
samtools fqidx {output.FQO}
"""

TASK_HASM_COLLECT_SCRIPT = """\
## prepare for quviering the haplotig
## (assume we are in 3-unzip/somewhere/)

# TODO: Stop using job_done.
python3 -m falcon_unzip.mains.graphs_to_h_tigs_2 combine --results-fn={input.results} --done-fn={output.job_done}

find ./0-phasing -name "phased_reads" | sort | xargs cat >| all_phased_reads
#find ./2-htigs -name "h_ctg_ids.*" | sort | xargs cat >| all_h_ctg_ids
#find ./2-htigs -name "p_ctg_edges.*" | sort | xargs cat >| all_p_ctg_edges
#find ./2-htigs -name "h_ctg_edges.*" | sort | xargs cat >| all_h_ctg_edges
#find ./2-htigs -name "p_ctg.*.fasta" | sort | xargs cat >| all_p_ctg.fasta
#find ./2-htigs -name "h_ctg.*.fasta" | sort | xargs cat >| all_h_ctg.fasta

if [[ ! -s all_p_ctg.fasta ]]; then
    echo "Empty all_p_ctg.fasta -- No point in continuing!"
    exit 1
fi

samtools faidx all_p_ctg.fasta

# # Generate a GFA for only primary contigs and haplotigs.
# time python3 -m falcon_unzip.mains.unzip_gen_gfa_v1 --unzip-root . --p-ctg-fasta ./all_p_ctg.fasta --h-ctg-fasta ./all_h_ctg.fasta --preads-fasta {input.preads4falcon} >| ./asm.gfa

# # Generate a GFA of all assembly graph edges. This GFA can contain
# # edges and nodes which are not part of primary contigs and haplotigs
# time python3 -m falcon_unzip.mains.unzip_gen_gfa_v1 --unzip-root . --p-ctg-fasta ./all_p_ctg.fasta --h-ctg-fasta ./all_h_ctg.fasta --preads-fasta {input.preads4falcon} --add-string-graph >| ./sg.gfa
"""


TASK_GRAPH_TO_H_TIGS_SCRIPT = """\
asm_dir=$(dirname {input.falcon_asm_done})
hasm_dir=$(dirname {input.p_ctg})

python3 -m falcon_unzip.mains.graphs_to_h_tigs_2 --gathered-rid-to-phase={input.gathered_rid_to_phase} --base-dir={params.topdir} --fc-asm-path ${{asm_dir}} --fc-hasm-path ${{hasm_dir}} --ctg-id all --rid-phase-map {input.rid_to_phase_all} --fasta {input.preads4falcon}

# more script -- a little bit hacky here, we should improve

#WD=$PWD
# for f in `cat ../reads/ctg_list `; do mkdir -p $WD/$f; cd $WD/$f; python3 -m falcon_unzip.mains.dedup_h_tigs $f; done

for f in `cat ../reads/ctg_list `
do
    mkdir -p ./$f;
    if [ -s ./$f/h_ctg.$f.fasta ]
    then
        grep ">" ./$f/h_ctg.$f.fasta | sed "s/^>//" >| ./$f/h_ctg_ids.$f
    else
        rm -rf ./$f/h_ctg_ids.$f
        touch ./$f/h_ctg_ids.$f
    fi
done

touch {output.htigs_done}
"""

TASK_GRAPH_TO_H_TIGS_SPLIT_SCRIPT = """\
asm_dir=$(dirname {input.falcon_asm_done})
hasm_dir=$(dirname {input.p_ctg})

# TODO: Should we look at ../reads/ctg_list ?

python3 -m falcon_unzip.mains.graphs_to_h_tigs_2 split \
        --gathered-rid-to-phase={input.gathered_rid_json} --base-dir={params.topdir} \
        --fc-asm-path ${{asm_dir}} --fc-hasm-path ${{hasm_dir}} \
        --rid-phase-map {input.rid_to_phase_all} --fasta {input.preads4falcon} \
        --split-fn={output.split} --bash-template-fn={output.bash_template}

# The bash-template is just a dummy, for now.
"""


TASK_HASM_SCRIPT = """\
# TODO: Needs preads.db

rm -f ./ctg_paths
python3 -m falcon_unzip.mains.ovlp_filter_with_phase_strict \
        --fofn {input.las_fofn} --max-diff 120 --max-cov 120 --min-cov 1 \
        --n-core {params.pypeflow_nproc} --min-len 2500 --db {input.preads_db} \
        --rid-phase-map {input.rid_to_phase_all} > preads.p_ovl
python3 -m falcon_unzip.mains.phased_ovlp_to_graph preads.p_ovl --min-len 2500 > fc.log

if [[ ! -e ./ctg_paths ]]; then
    exit 1
fi

rm -f preads.p_ovl

# Create haplotigs in a safe manner.

ln -sf {input.preads4falcon} .

rm -f {output.p_ctg}

# Given sg_edges_list, utg_data, ctg_paths, preads4falcon.fasta,
# write p_ctg.fasta and a_ctg_all.fasta,
# plus p_ctg_tiling_path, a_ctg_tiling_path:
time python3 -m falcon_kit.mains.graph_to_contig

if [[ ! -e {output.p_ctg} ]]; then
    exit 1
fi
"""

TASK_PHASING_GATHER_SCRIPT = """\
# creates a master table of rid to phase
cat {input.ctg*} > {output.rid_to_phase_all}

# creates the needed gathering JSON
find {input.ctg*} | xargs -I [] readlink -f [] | python3 -m falcon_unzip.mains.gen_rid_gathered_json > {output.gathered_rid_json}
"""

TASK_READ_PHASING = """

        #TODO: break up command, and maybe remove some deps.

        python3 -m falcon_unzip.mains.phasing_make_het_call --ctg-id {params.ctg} --bam-fn {input.BAM} --fasta-fn {input.T} --vmap-fn het_calls.ctg.vmap --vpos-fn het_calls.ctg.vpos --q-id-map-fn het_calls.ctg.msgpack
        python3 -m falcon_unzip.mains.phasing_generate_association_table --ctg-id {params.ctg} --vmap=het_calls.ctg.vmap --atable=association_table.ctg.astab
        python3 -m falcon_unzip.mains.phasing_get_phased_blocks --vmap=het_calls.ctg.vmap --atable=association_table.ctg.astab --p-variant=phased_vars.ctg.phased.txt
        python3 -m falcon_unzip.mains.phasing_get_phased_reads --ctg-id={params.ctg} --vmap=het_calls.ctg.vmap --p-variant=phased_vars.ctg.phased.txt --q-id-map=het_calls.ctg.msgpack --phased-reads=phased_reads.ctg.phased.txt

        #reformats the data keeping the last, second..forth columns
        cat phased_reads.ctg.phased.txt | perl -lane 'print "$F[-1] $F[1] $F[2] $F[3]"' >|   phased_reads.ctg.phased.reads.reformat.txt

        mkdir -p proto

        #pulls the reference into the proto dir
        samtools faidx {input.T} {params.ctg} > proto/ref.fasta

        python3 -m falcon_unzip.proto.main_augment_pb --wd ./proto/ --ctg-id {params.ctg}     --p-ctg {input.PCTG} --p-ctg-tiling-path {input.PTILE} --a-ctg {input.ACTG} --a-ctg-tiling-path {input.ATILE}  --p-variant-fn phased_vars.ctg.phased.txt --preads-sam {input.BAM}  --extracted-ctg-fasta {input.T} --rawread-bam {input.BAM}  --rid-phase-map phased_reads.ctg.phased.reads.reformat.txt  --out-updated-rid-phase_map rid_to_phase.tmp

        #grabs the names of all the CCS reads that associate with this primary contig.
        (
        set -vx +e
        grep -w {params.ctg} {input.RID_TO_CTG} >| rid_to_ctg.txt
        true
        )

        #converts the CCS read names into DAZDB read ids.
        python3 -m falcon_unzip.mains.db_to_ccs_id --lookup {input.readname_lookup} --rid-to-phase rid_to_phase.tmp --rid-to-ctg rid_to_ctg.txt --output {output.M} --ctg {params.ctg}

        python3 -m falcon_unzip.proto.extract_phased_preads --ctg-id {params.ctg} --preads ../../../../1-preads_ovl/db2falcon/preads4falcon.fasta --rid-phase-map {output.M} --out proto/preads.fasta

        time pbmm2 align --preset CCS --sort -j 1 proto/ref.fasta proto/preads.fasta | samtools view  > proto/preads.sam
"""


TASK_READNAME_LOOKUP = """
       #TODO: move into a script rather than a hard to grok command line.
       #This command makes a two column file where one column is the CCS read name and the other is DAZDB ID.


       paste <(DBdump -hr ../../1-preads_ovl/build/preads.db | grep "^L" ) <(DBdump -hr ../../1-preads_ovl/build/preads.db | grep "^H" ) | perl -lane '$ln = sprintf("%09d", $. -1); @Z = split /\s+/, $_; print "$ln\t$Z[-1]/$Z[1]/ccs"' > {output.readname_lookup}
"""

TASK_MAP = """
        time pbmm2 align --sort --preset CCS -j {params.pypeflow_nproc} {input.T} {input.R} | samtools view -F 3840 -bS > {output.BAM}
        time samtools index {output.BAM}
        time samtools view -F 3844 {output.BAM}  | perl -lane '$F[2] =~ s/\-.*//; print "$F[0] $F[2]"' > {output.RID_TO_CTG}
"""
TASK_PREAMBLE = """
        cat {input.P} {input.A} > {output.FA}
        samtools faidx {output.FA}
"""



def run_workflow(wf, config, unzip_config_fn):
    default_njobs = int(config['job.defaults']['njobs'])
    wf.max_jobs = default_njobs

    #LOG.info('config=\n {}'.format(config))
    Unzip_config = config['Unzip']

    falcon_asm_done_fn = './2-asm-falcon/falcon_asm_done'

    #ifastq_fn = '/home/zkronenberg/dump/hg002_chr6_dataset/hg002_chr6_size_filt.fq'
    ifastq_fn = Unzip_config['fastq']
    LOG.info('Input fastq="{}"'.format(ifastq_fn))

    asm_dir = './2-asm-falcon'
    p_ctg_fn = os.path.join(asm_dir, 'p_ctg.fasta')
    a_ctg_fn = os.path.join(asm_dir, 'a_ctg.fasta')
    p_tile_fn = os.path.join(asm_dir, 'p_ctg_tiling_path')
    a_tile_fn = os.path.join(asm_dir, 'a_ctg_tiling_path')

    # Typical job-dist configuration
    dist_default = Dist(
        job_dict=config['job.defaults'],
        use_tmpdir=False, # until we fix a bug in pypeflow
    )

    # high resource configuration
    dist_high = Dist(
        job_dict=config['job.high'],
        use_tmpdir=False, # until we fix a bug in pypeflow
    )

    # 1-proc jobs
    dist_one = Dist(
        NPROC = 1,
        use_tmpdir=False, # until we fix a bug in pypeflow
    )

    # 1-proc high mem jobs like htig
    dist_highmem = Dist(
        job_dict=config['job.highmem'],
        use_tmpdir=False, # until we fix a bug in pypeflow
    )

    # For strictly local jobs, use this.
    dist_local = Dist(
        local=True,
        NPROC=1,
        use_tmpdir=False, # until we fix a bug in pypeflow
    )


    '''
    In this task we combine the p and a ctg files into one and index it with samtools faidx.
    '''

    p_ctg_fai_fn = "./2-asm-falcon/p_ctg.fasta.fai"

    wf.addTask(gen_task(
            script=TASK_PREAMBLE,
            inputs={
                "P": p_ctg_fn,
                "A": a_ctg_fn,
            },
            outputs={
                "FA": "3-unzip/ctgs/concat.fasta",
                "FAI": "3-unzip/ctgs/concat.fasta.fai",
            },
            parameters={},
            dist=dist_one,
    ))

    wf.refreshTargets()

    top.fai2ctgs(p_ctg_fai_fn, '3-unzip/ctg_tracking/CTGS.json')
    CTGS = io.deserialize('3-unzip/ctg_tracking/CTGS.json')  # currently in top-dir

    '''
    In this task we use pbmm2 to map all the fastq records to the combined p&a ctgs.
     - Secondary, chimeric, duplicates are filtered out
     - pbmm2 sorts the alignments
    '''

    mapped_reads       = "3-unzip/mapping/reads_mapped.sorted.bam"
    mapped_reads_index = "3-unzip/mapping/reads_mapped.sorted.bam.bai"
    rid_to_ctg         = "./3-unzip/mapping/rid_to_cgt.txt"


    wf.addTask(gen_task(
            script=TASK_MAP,
            inputs={
                "T": "3-unzip/ctgs/concat.fasta",
                "R": ifastq_fn,
            },
            outputs={
                "BAM": mapped_reads,
                "BAI": mapped_reads_index,
                "RID_TO_CTG" : rid_to_ctg,
            },
            parameters={},
            dist=dist_high,
    ))

    readname_lookup = "3-unzip/readnames/readname_lookup.txt"


    '''
    In this task the pread databases are dumped two different way to reconstitute to build a mapping of read ID <-> DB id
    '''

    wf.addTask(gen_task(
            script=TASK_READNAME_LOOKUP,
            inputs={
                "BAI": mapped_reads_index
            },
            outputs={
                'readname_lookup'  : readname_lookup,
            },
            parameters={},
            dist=dist_one,
    ))

    collected = dict()

    '''
    Reads are phased in this task.
    '''

    for ctg in CTGS:
        rid_to_phase_fn = "3-unzip/0-phasing/{}/uow-fake/rid_to_phase".format(ctg)
        collected['ctg' + ctg] = rid_to_phase_fn
        wf.addTask(gen_task(
            script=TASK_READ_PHASING,
            inputs={
                "PCTG": p_ctg_fn,
                "ACTG": a_ctg_fn,
                "PTILE": p_tile_fn,
                "ATILE": a_tile_fn,
                "BAM": "3-unzip/mapping/reads_mapped.sorted.bam",
                "T": "3-unzip/ctgs/concat.fasta",
                "readname_lookup" : readname_lookup,
                "RID_TO_CTG"      : rid_to_ctg,
            },
            outputs={
                "M": rid_to_phase_fn,
            },
            parameters={
                'ctg': ctg,
            },
            dist=dist_one,
        ))

    wf.refreshTargets()

    check(sorted(collected.values()), sorted(glob.glob('3-unzip/0-phasing/*/uow-fake/rid_to_phase')))

    '''
    This task gathers the phasing information and condenses it to a single file.
    '''

    concatenated_rid_to_phase_fn = "3-unzip/0-phasing/gathered-rid-to-phase/rid_to_phase.all"
    gathered_rid_to_phase_json   = "3-unzip/0-phasing/gathered-rid-to-phase/gathered.json"

    wf.addTask(gen_task(
        script=TASK_PHASING_GATHER_SCRIPT,
        inputs=collected,
        outputs={'rid_to_phase_all'  : concatenated_rid_to_phase_fn,
                 'gathered_rid_json' : gathered_rid_to_phase_json,
        },
        parameters={},
        dist=dist_local,
    ))

    p_las_fofn_fn =   './1-preads_ovl/las-merge-combine/las_fofn.json'
    hasm_p_ctg_fn    = './3-unzip/1-hasm/p_ctg.fasta'
    preads_db_fn     = './1-preads_ovl/build/preads.db'
    preads4falcon_fn = './1-preads_ovl/db2falcon/preads4falcon.fasta'

    wf.addTask(gen_task(
            script=TASK_HASM_SCRIPT,
            inputs={
                'preads_db': preads_db_fn,
                'preads4falcon': preads4falcon_fn,
                'las_fofn': p_las_fofn_fn,
                'rid_to_phase_all': concatenated_rid_to_phase_fn,
                'gathered_rid_json' : gathered_rid_to_phase_json,
            },
            outputs={
                'p_ctg': hasm_p_ctg_fn,
            },
            parameters={},
            dist=dist_default,
    ))

    g2h_all_units_fn = './3-unzip/2-htigs/split/all-units-of-work.json'
    dummy_fn = './3-unzip/2-htigs/split/dummy.sh'
    wf.addTask(gen_task(
            script=TASK_GRAPH_TO_H_TIGS_SPLIT_SCRIPT,
            inputs={
                'falcon_asm_done': falcon_asm_done_fn,
                'preads4falcon': preads4falcon_fn,
                'rid_to_phase_all': concatenated_rid_to_phase_fn,
                'gathered_rid_json': gathered_rid_to_phase_json,
                'p_ctg': hasm_p_ctg_fn,
            },
            outputs={
                'split': g2h_all_units_fn,
                'bash_template': dummy_fn,
            },
            parameters={},
            dist = dist_highmem,
    ))

    wf.refreshTargets()

    TASK_GTOH_APPLY_UNITS_OF_WORK = """\
    python3 -m falcon_unzip.mains.graphs_to_h_tigs_2 apply --units-of-work-fn={input.units_of_work} --results-fn={output.results}

    #--bash-template-fn= # not needed
    """
    gathered_g2h_fn = './3-unzip/2-htigs/gathered/gathered.json'
    gen_parallel_tasks(
        wf,
        g2h_all_units_fn, gathered_g2h_fn,
        run_dict=dict(
            bash_template_fn=dummy_fn,
            script='DUMMY',
            inputs={
                'units_of_work': './3-unzip/2-htigs/chunks/{chunk_id}/some-units-of-work.json',
            },
            outputs={
                'results': './3-unzip/2-htigs/{chunk_id}/result-list.json',
            },
            parameters={},
        ),
        dist=dist_highmem,  # single-threads for now
        run_script=TASK_GTOH_APPLY_UNITS_OF_WORK,
    )


    job_done = './3-unzip/hasm_done'
    wf.addTask(gen_task(
            script=TASK_HASM_COLLECT_SCRIPT,
            inputs={
                'preads4falcon': preads4falcon_fn,
                'results': gathered_g2h_fn,
            },
            outputs={
                'job_done': job_done,
                'all_phased_reads': './3-unzip/all_phased_reads',
                'p_ctg_fa': './3-unzip/all_p_ctg.fasta',
                'h_ctg_fa': './3-unzip/all_h_ctg.fasta',
            },
            parameters={},
            dist=dist_one,
    ))

    combined_ph     = "./4-polish/input/combined_ph.fasta"
    combined_ph_fai = "./4-polish/input/combined_ph.fasta.fai"
    combined_eg     = "./4-polish/input/combined_edges.txt"
    ofastq_fn       = "./4-polish/input/preamble.fastq"

    readtoctg       = "./4-polish/input/read2ctg.txt"

    wf.addTask(gen_task(
        script=TASK_POLISH_PREAMBLE,
        inputs={
            'P': './3-unzip/all_p_ctg.fasta',
            'H': './3-unzip/all_h_ctg.fasta',
            'RIDTOPHASE' : './3-unzip/0-phasing/gathered-rid-to-phase/rid_to_phase.all',
            'READNAMELOOKUP' : './3-unzip/readnames/readname_lookup.txt',
            'FQ'             : ifastq_fn,
        },
        outputs={
            'COMBINED' : combined_ph,
            'EDGES' : combined_eg,
            'READTOCTG' : readtoctg,
            "FAI"       : combined_ph_fai,
            "FQO"       : ofastq_fn,
        },
        parameters={},
        dist=dist_one,
    ))

    wf.refreshTargets()

    collected = dict()

    unzip_p_ctg_fai_fn = "3-unzip/all_p_ctg.fasta.fai"
    top.fai2ctgs(unzip_p_ctg_fai_fn, '3-unzip/ctg_tracking/PUCTGS.json')
    PUCTGS = io.deserialize('3-unzip/ctg_tracking/PUCTGS.json')  # currently in top-dir

    for ctg in PUCTGS:
        fn = '4-polish/temp-unphased/{}/aln.bam'.format(ctg)
        collected['ctg'+ctg] = fn
        wf.addTask(gen_task(
            script=TASK_PLACE_UNPHASED,
            inputs={
                "fa"  : combined_ph,
                "fai" : combined_ph_fai,
                "fq"  : ofastq_fn,
                "readtoctg" : readtoctg,
            },
            outputs={
                "POL": fn,
            },
            parameters={
                'ctg': ctg,
            },
            dist=dist_one,
        ))

    wf.refreshTargets()

    merged_unphased = "4-polish/merged-unphased/merged_unphased.sorted.bam"
    reads2ctgaug    = "4-polish/merged-unphased/read2ctg_aug.txt"

    collected['READTOCTG'] = readtoctg

    wf.addTask(gen_task(
        script=TASK_GATHER_UNPHASED,
        inputs=collected,
        outputs={
            "UBAM": merged_unphased,
            "READTOCTG_AUG": reads2ctgaug,
        },
        parameters={},
        dist=dist_one,
    ))

    wf.refreshTargets()

    PH = top.getPH(combined_ph_fai, reads2ctgaug)

    fns = list()
    LOG.info('len(PH)={}, {!r}'.format(len(PH), dist_default))
    for ctg in PH:
        fn = "4-polish/temp-phased/{}/{}.polished.fasta".format(ctg, ctg)
        fns.append(fn)
        wf.addTask(gen_task(
            script=TASK_POLISH,
            inputs={
                "FA" : combined_ph,
                "FQ" : ifastq_fn,
                "READTOCTG" : reads2ctgaug,
                "UBAM"      : merged_unphased
            },
            outputs={
                "POL": fn,
            },
            parameters={
                'ctg': ctg,
            },
            dist=dist_default,
        ))

    wf.refreshTargets()

    final_ctgs  ='4-polish/ctg_tracking/polished.json'
    final_p_ctgs_fn='4-polish/cns-output/polished_p_ctgs.fasta'
    final_h_ctgs_fn='4-polish/cns-output/polished_h_ctgs.fasta'

    io.serialize(final_ctgs, fns)

    wf.addTask(gen_task(
        script=TASK_GATHER_POLISH,
        inputs={
            "FNS" : final_ctgs,
        },
        outputs={
            "FP": final_p_ctgs_fn,
            "FH": final_h_ctgs_fn,
        },
        dist=dist_one,
    ))

    wf.refreshTargets()

def check(a, b):
    """Simple runtime equality checking.
    """
    if a != b:
        LOG.warning('a != b\n{!r} !=\n{!r}'.format(a, b))
    assert a == b
