#!/usr/bin/env bash

export SNAKEMAKE_SINGULARITY_CMD="apptainer"


timestamp=$(date +%Y%m%d%H%M%S);

CONFIG_FILE=~/.config/daylily/daylily_cli_global.yaml
export TMPDIR=$(yq -r '.daylily.sentieon_tmpdir' "$CONFIG_FILE")
mkdir -p $TMPDIR;
export TMP=$TMPDIR
export TEMP=$TMPDIR

if [[ "$DAY_REMOTE_EXE" == "remote" ]]; then
    echo "Remote call detected. Activating conda hack"
    . "$HOME/miniconda3/etc/profile.d/conda.sh"
    export PATH="/home/ubuntu/miniconda3/bin:$PATH"
    conda activate DAYOA
fi

if [[ -z "$DAY_ROOT" || -z "$DAY_PROFILE" || -z "$DAY_PROFILE_DIR" ]]; then
    colr "ERROR: . dayiniy && day-activate [local|slurm] needs to have been run prior to day-run."  "$DY_WT0" "$DY_WB0" "$DY_WS1" 1>&2
    exit 33
fi
if [[ ! -d "$DAY_PROFILE_DIR" ]]; then
    colr "ERROR: Profile directory: $DAY_PROFILE_DIR does not exist." "$DY_WT0" "$DY_WB0" "$DY_WS1" 1>&2
    exit 3
fi

if [[ -z "$DAY_GENOME_BUILD" ]]; then
    colr "ERROR: Genome build not set. Please run 'dy-g [b37|hg38]'." "$DY_WT0" "$DY_WB0" "$DY_WS1" 1>&2
    exit 3
fi

source bin/util/profile_freshness_warn.bash
if [[ "$?" == "3" ]]; then
    colr "ERROR: source bin/util/profile_freshness_warn.bash"  "$DY_WT0" "$DY_WB0" "$DY_WS1" 1>&2
    return 4
fi

# Check if we're in the correct root
if [[ "$(pwd)" != "$DAY_ROOT"* ]]; then
    colr "|||<<<
___________________

    You are not in the correct DAY_ROOT

    **>> DETECTED:     $PWD

    **>> EXPECTED:     $DAY_ROOT

    
___________________

    >>>|||" "$DY_ET0" "$DY_EB0" "$DY_ES1" 1>&2
    echo ""
    echo "Please run 'day-deactivate' and 'day-activate' from the intended analysis deployment directory."
    exit 3
fi



# ---------------------------------------------------------------------------
# Auto-detect aligner / deduper config from target rule names on the CLI.
# If the user specifies target rules like dedup_doppelmark or
# produce_bwa_mem2_sort_bam, we inject the corresponding --config values
# so downstream expand() calls see a populated ALIGNERS / DDUP list.
# Explicit --config aligners=... / dedupers=... always takes priority.
# ---------------------------------------------------------------------------
_dedup_codes=()
_aligner_codes=()
_snv_caller_codes=()
_has_dedupers_config=false
_has_aligners_config=false
_has_snv_callers_config=false
_is_dry_run=false

for _arg in "$@"; do
    # Detect dedup targets
    case "$_arg" in
        dedup_doppelmark)       _dedup_codes+=("dmd")   ;;
        dedup_sentieon)         _dedup_codes+=("smd")   ;;
        dedup_none)             _dedup_codes+=("na")    ;;
    esac
    # Detect aligner targets
    case "$_arg" in
        produce_bwa_mem2_sort_bam)      _aligner_codes+=("bwa2a")       ;;
        produce_sentieon_bwa_sort_bam)  _aligner_codes+=("sent")        ;;
        produce_sentieon_cgt7p_bwa_sort_bam) _aligner_codes+=("sentcg") ;;
        produce_cgt7p_vcf)              _aligner_codes+=("sentcg")      ;;
        produce_strobe_align_sort_bam)  _aligner_codes+=("strobe")      ;;
        produce_sentmm2_align_sort)     _aligner_codes+=("sentmm2")     ;;
        produce_sentmm2ont_align_sort)  _aligner_codes+=("sentmm2ont")  ;;
    esac
    # Detect SNV caller targets
    case "$_arg" in
        produce_sentD_vcf)              _snv_caller_codes+=("sentd")     ;;
        produce_cgt7p_vcf)              _snv_caller_codes+=("cgt7p")     ;;
        produce_sentdpb_vcf)            _snv_caller_codes+=("sentdpb")   ;;
        produce_sentdont_vcf)           _snv_caller_codes+=("sentdont")  ;;
        produce_sentdug_vcf)            _snv_caller_codes+=("sentdug")   ;;
        # Hybrid CLI callers
        produce_sentdhio_vcf)           _snv_caller_codes+=("sentdhio")  ;;
        produce_sentdhuo_vcf)           _snv_caller_codes+=("sentdhuo")  ;;
        produce_sentdhip_vcf)           _snv_caller_codes+=("sentdhip")  ;;
        produce_sentdhup_vcf)           _snv_caller_codes+=("sentdhup")  ;;
        # Hybrid modular callers
        produce_sentdhiom_vcf)          _snv_caller_codes+=("sentdhiom") ;;
        produce_sentdhuom_vcf)          _snv_caller_codes+=("sentdhuom") ;;
        produce_sentdhipm_vcf)          _snv_caller_codes+=("sentdhipm") ;;
        produce_sentdhupm_vcf)          _snv_caller_codes+=("sentdhupm") ;;
        produce_sentdhrom_vcf)          _snv_caller_codes+=("sentdhrom") ;;
        produce_sentdhrpm_vcf)          _snv_caller_codes+=("sentdhrpm") ;;
        # Other callers
        produce_sentpg_vcf)             _snv_caller_codes+=("sentpg")    ;;
        produce_deep19_vcf)             _snv_caller_codes+=("deep19")    ;;
        produce_deep19_r_vcf)           _snv_caller_codes+=("deep19r")   ;;
        produce_deep15_vcf)             _snv_caller_codes+=("deep15")    ;;
        produce_oct_vcf)                _snv_caller_codes+=("oct")       ;;
        produce_clair3_vcf)             _snv_caller_codes+=("clair3")    ;;
        produce_lofreq2_vcf)            _snv_caller_codes+=("lfq2")      ;;
        produce_varn_vcf)               _snv_caller_codes+=("varn")      ;;
        produce_aiv_vcf)                _snv_caller_codes+=("aiv")       ;;
        produce_mutect2_vcf)            _snv_caller_codes+=("mutect2")   ;;
        produce_dvsom_vcf)              _snv_caller_codes+=("dvsom")     ;;
        produce_strelka2_germline_vcf)  _snv_caller_codes+=("slk2g")     ;;
        produce_strelka2_somatic_vcf)   _snv_caller_codes+=("slk2s")     ;;
        produce_sent_TNscope_vcf)       _snv_caller_codes+=("senttn")    ;;
        produce_rochehc_vcf)            _snv_caller_codes+=("rochehc")   ;;
    esac
    # Check if user already specified these config keys
    case "$_arg" in
        dedupers=*)      _has_dedupers_config=true      ;;
        aligners=*)      _has_aligners_config=true       ;;
        snv_callers=*)   _has_snv_callers_config=true    ;;
    esac
    # Detect dry-run flags
    case "$_arg" in
        -n|--dry-run|--dryrun)  _is_dry_run=true  ;;
    esac
done

# Export auto-detected config as environment variables for common.smk.
# This avoids Snakemake's --config nargs="*" consuming target names.
if [[ ${#_dedup_codes[@]} -gt 0 ]] && [[ "$_has_dedupers_config" == "false" ]]; then
    _dedup_csv=$(IFS=,; echo "${_dedup_codes[*]}")
    export _DY_AUTO_DEDUPERS="$_dedup_csv"
    colr "...AUTO-CONFIG: dedupers=${_dedup_csv} (from target rules → env)" "$DY_IT1" "$DY_IB1" "$DY_IS1" 1>&2
fi

if [[ ${#_aligner_codes[@]} -gt 0 ]] && [[ "$_has_aligners_config" == "false" ]]; then
    _aligner_csv=$(IFS=,; echo "${_aligner_codes[*]}")
    export _DY_AUTO_ALIGNERS="$_aligner_csv"
    colr "...AUTO-CONFIG: aligners=${_aligner_csv} (from target rules → env)" "$DY_IT1" "$DY_IB1" "$DY_IS1" 1>&2
fi

if [[ ${#_snv_caller_codes[@]} -gt 0 ]] && [[ "$_has_snv_callers_config" == "false" ]]; then
    _snv_csv=$(IFS=,; echo "${_snv_caller_codes[*]}")
    export _DY_AUTO_SNV_CALLERS="$_snv_csv"
    colr "...AUTO-CONFIG: snv_callers=${_snv_csv} (from target rules → env)" "$DY_IT1" "$DY_IB1" "$DY_IS1" 1>&2
fi

# Build the snakemake command — targets pass through unchanged.
snakecmd_init=("snakemake" "--profile=$DAY_PROFILE_DIR" "$@")

snakecmd="${snakecmd_init[@]//\-\-keep-temp/\-\-notemp}"

# This ensures the snakedir is unlocked after a crash or successful exit 0
trap "(snakemake --unlock --profile $DAY_PROFILE_DIR  &>> ./unlock_fails.log & ) & " EXIT

# Log the command
cmd_log="$PWD/day_cmd.log"
cmddt=$(date --iso-8601="seconds")
echo "SMK> D:$cmddt / U:$USER / PWD:$PWD / CMD: (${snakecmd[*]})" >> "$cmd_log"

# Run snakemake command
colr "Executing: ${snakecmd[*]}"  "$DY_IT0" "$DY_IB0" "$DY_IS1"  1>&2
if [[ "$_is_dry_run" == "true" ]]; then
    $snakecmd
else
    ( $snakecmd && echo "$(date '+%Y-%m-%d %H:%M:%S')" >> daylily.successful_run && bash bin/util/benchmarks/collect_day_benchmark_data.sh  $DAY_GENOME_BUILD > /dev/null 2>&1 ) || echo "$(date '+%Y-%m-%d %H:%M:%S')" >> daylily.failed_run
fi
ret_code=$?

colr "RETURN CODE: $ret_code" "$DY_IB0" "$DY_IT0" "$DY_IS0" 1>&2
exit $ret_code
