#!/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

profile_env_script="$DAY_PROFILE_DIR/templates/profile_env.bash"
if [[ -f "$DAY_PROFILE_DIR/profile_env.bash" ]]; then
    profile_env_script="$DAY_PROFILE_DIR/profile_env.bash"
fi
if [[ ! -f "$profile_env_script" ]]; then
    colr "ERROR: Profile environment script not found for $DAY_PROFILE_DIR." "$DY_WT0" "$DY_WB0" "$DY_WS1" 1>&2
    exit 3
fi
source "$profile_env_script"
profile_env_ret_code=$?
if [[ "$profile_env_ret_code" != "0" ]]; then
    colr "ERROR: Profile environment script failed before Snakemake launch: $profile_env_script" "$DY_WT0" "$DY_WB0" "$DY_WS1" 1>&2
    exit "$profile_env_ret_code"
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=()
_sv_caller_codes=()
_has_dedupers_config=false
_has_aligners_config=false
_has_snv_callers_config=false
_has_sv_callers_config=false
_is_dry_run=false
_DY_TARGET_REGISTRY="${DAY_ROOT:-.}/config/workflow_target_aliases.tsv"

_dy_add_auto_code() {
    local _kind="$1"
    local _code="$2"
    case "$_kind" in
        aligner)     _aligner_codes+=("$_code") ;;
        deduper)     _dedup_codes+=("$_code") ;;
        snv_caller)  _snv_caller_codes+=("$_code") ;;
        sv_caller)   _sv_caller_codes+=("$_code") ;;
    esac
}

_dy_add_registry_target_codes() {
    local _target="$1"
    local _kind="$2"
    local _rtarget _rkind _rcode _rstatus _rdelegates
    [[ -f "$_DY_TARGET_REGISTRY" ]] || return 0
    while IFS=$'\t' read -r _rtarget _rkind _rcode _rstatus _rdelegates; do
        [[ "$_rtarget" == "$_target" && "$_rkind" == "$_kind" ]] || continue
        if [[ "$_rcode" == "all" ]]; then
            local _atarget _akind _acode _astatus _adelegates
            while IFS=$'\t' read -r _atarget _akind _acode _astatus _adelegates; do
                [[ "$_akind" == "$_kind" && "$_astatus" == "current" && "$_acode" != "all" ]] || continue
                _dy_add_auto_code "$_kind" "$_acode"
            done < "$_DY_TARGET_REGISTRY"
        else
            _dy_add_auto_code "$_kind" "$_rcode"
        fi
    done < "$_DY_TARGET_REGISTRY"
}

_dy_unique_csv() {
    printf '%s\n' "$@" | awk 'NF && !seen[$0]++' | paste -sd, -
}

for _arg in "$@"; do
    _dy_add_registry_target_codes "$_arg" aligner
    _dy_add_registry_target_codes "$_arg" deduper
    _dy_add_registry_target_codes "$_arg" snv_caller
    _dy_add_registry_target_codes "$_arg" sv_caller
    # 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    ;;
        sv_callers=*)    _has_sv_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=$(_dy_unique_csv "${_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=$(_dy_unique_csv "${_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=$(_dy_unique_csv "${_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

if [[ ${#_sv_caller_codes[@]} -gt 0 ]] && [[ "$_has_sv_callers_config" == "false" ]]; then
    _sv_csv=$(_dy_unique_csv "${_sv_caller_codes[@]}")
    export _DY_AUTO_SV_CALLERS="$_sv_csv"
    colr "...AUTO-CONFIG: sv_callers=${_sv_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
