#!/bin/bash

# Skrypt timein wyświetlający bieżący czas w zadanej strefie lub obszarze
# geograficznym. Wywołany bez argumentów podaje czas UTC/GMT.
# Aby wyświetlić listę stref, użyj argumentu "list". Zwróć uwagę,
# że argument może określać katalog stref (regionów), ale
# poprawny argument powinien zawierać nazwę pliku (miasta).

# Baza stref czasowych: http://www.twinsun.com/tz/tz-link.htm.

zonedir="/usr/share/zoneinfo"

if [ ! -d $zonedir ] ; then
  echo "Brak bazy stref w katalogu $zonedir." >&2 ; exit 1
fi

if [ -d "$zonedir/posix" ] ; then
  zonedir=$zonedir/posix        # Katalog w mowoczesnym systemie Linux.
fi

if [ $# -eq 0 ] ; then
  timezone="UTC"
  mixedzone="UTC"
elif [ "$1" = "list" ] ; then
  ( echo "Wszystkie strefy czasowe i regiony zdefiniowane w systemie:"
    cd $zonedir
    find -L * -type f -print | xargs -n 2 | \
      awk '{ printf "  %-38s %-38s\n", $1, $2 }' 
  ) | more
  exit 0
else

  region="$(dirname $1)"
  zone="$(basename $1)"

  # Czy podany argument jednoznacznie określa strefę czasową? Jeżeli tak, to dobrze.
  # W przeciwnym wypadku trzeba trochę poszukać. Najpierw należy określić
  # liczbę stref odpowiadających podanemu wzorcowi.

  matchcnt="$(find -L $zonedir -name $zone -type f -print |
        wc -l | sed 's/[^[:digit:]]//g' )"
  # Sprawdzenie, czy wzorcowi odpowiada przynajmniej jeden plik.
  if [ "$matchcnt" -gt 0 ] ; then
    # Wyjście, jeżeli jest więcej niż jeden plik.
    if [ $matchcnt -gt 1 ] ; then
      echo "Argument \"$zone\" opisuje więcej niż jedną strefę czasową." >&2
      echo "Użyj argumentu 'list', aby wyświetlić listę wszystkich regionów " \
        "i stref czasowych." >&2
      exit 1
    fi
    match="$(find -L $zonedir -name $zone -type f -print)"
    mixedzone="$zone" 
  else # Być może uda się znaleźć region, a nie strefę czasową.
    # Pierwsza litera ciągu region + strefa jest wielka, pozostałe małe.
    mixedregion="$(echo ${region%${region#?}} \
                 | tr '[[:lower:]]' '[[:upper:]]')\
                 $(echo ${region#?} | tr '[[:upper:]]' '[[:lower:]]')"
    mixedzone="$(echo ${zone%${zone#?}} | tr '[[:lower:]]' '[[:upper:]]') \
               $(echo ${zone#?} | tr '[[:upper:]]' '[[:lower:]]')"

    if [ "$mixedregion" != "." ] ; then
      # Jeżeli pasujących wyników jest więcej niż jeden (np. "Atlantic"),
      # wtedy wyszukujemy strefy czasowe w zadanym regionie,
      # aby użytkownik mógł wskazać żądaną strefę.
      match="$(find -L $zonedir/$mixedregion -type f -name $mixedzone -print)"
    else
      match="$(find -L $zonedir -name $mixedzone -type f -print)"
    fi

    # Jeżeli zadanemu wzorcowi odpowiada dokładnie jeden plik...
    if [ -z "$match"  ] ; then
      # ... sprawdzamy, czy wzorzec nie jest zbyt ogólny...
      if [ ! -z $(find -L $zonedir -name $mixedzone -type d -print) ] ; then
         echo "Region \"$1\" obejmuje więcej niż jedną strefę czasową. " >&2
      else  # ... albo czy nie odpowiada żadnej strefie.
        echo "Nie znaleziono strefy czasowej zgodnej ze wzorcem \"$1\". " >&2
      fi
      echo "Aby wyświetlić listę wszystkich regionów i stref czasowych, " \
        "użyj argumentu 'list'." >&2
      exit 1
    fi
  fi
  timezone="$match"
fi

nicetz=$(echo $timezone | sed "s|$zonedir/||g")    # Wyświetlenie wyniku 
                                                   # w czytelnym formacie.

echo W $nicetz jest teraz $(TZ=$timezone date '+%e.%m.%Y, godz. %H:%M').

exit 0
