#!/usr/bin/env bash
# Description: Outputs days until next timezone discontinuity
# Depends: GNU Coreutils 8.32 (date), zdump 2.35, Bash 5.1.16
#   BK-2020-03: yell(), die(), must()
# Version: 0.1.0

# User config
script_tz="America/Los_Angeles"; # Timezone to check for discontinuities

yell() { echo "$0: $*" >&2; } # Yell, Die, Try Three-Fingered Claw technique; # Ref/Attrib: https://stackoverflow.com/a/25515370
die() { yell "$*"; exit 111; }
must() { "$@" || die "cannot $*"; }
main() {
    declare -a datesDiscontArray; #array

    # plumbing
    script_year="$(date +%Y)";
    script_year_next="$(( script_year + 1 ))";
    script_year_next2="$(( script_year + 2 ))";
    script_run_date_seconds="$(date +%s)";

    # Get discontinuity dates from zdump (see https://stackoverflow.com/a/613580 )
    datesDiscont="$(zdump -c "$script_year","$script_year_next2" -v $script_tz | \
      grep "$script_year\|$script_year_next" | \
      awk '{ print $2 " " $3 " " $4 " " $5 " " $6 " " $7 }'; echo)"; # get dates
    if [[ -z "$datesDiscont" ]]; then
        yell "STATUS:No time discontinuity this year.";
        exit 1;
    fi;

    # Convert datesDiscont into array
    while read -r line; do
        tunix="$(date --date="$line" +%s)"; # get unix epoch seconds
        datesDiscontArray+=("$tunix");
    done < <(printf "%s\n" "$datesDiscont");

    # Sort datesDiscontArray
    while read -r line; do
        datesDiscontArray+=("$line");
    done < <(printf "%s\n" "${datesDiscontArray[@]}" | sort);

    # # Get earliest date in datesDiscontArray that isn't in the past.
    for discontinuityDate in "${datesDiscontArray[@]}"; do
        if [[ $discontinuityDate -gt $script_run_date_seconds ]]; then
            nextDiscontDate="$discontinuityDate";
            break;
        fi;
    done;

    # Check that nextDiscontDate is not empty
    if [[ -z "$nextDiscontDate" ]]; then
        die "FATAL:nextDiscontDate empty";
    fi;

    # Calculate days until next discontinuity date
    output="$(( ( nextDiscontDate - script_run_date_seconds )/86400 )) days";
    printf "%s\n" "$output";

}; # main program

main "$@";

# Author: Steven Baltakatei Sandoval
# License: GPLv3+