#!/bin/busybox sh
#
#   This program $FKSH_ONB/auth is customizable, and called at most twice
# from $FKSH_HOM/authenticate.sh
#   If the environment var KOBO_passwd is "", it is the first call from
# $FKSH_HOM/authenticate.sh. Then this program must output the password
# to stdout and return to $FKSH_HOM/authenticate.sh. The first arg "$1"
# is the number of seconds of slept period on waked up, or '' on boot.
# If the outputed password is "", it means no password, then 
# $FKSH_HOM/authenticate.sh dose not call for authorization, or no second call.
# Otherwise $FKSH_HOM/authenticate.sh sends STOP signals to other processes,
# nickel, etc. and call this program, second call, with the var KOBO_passwd set.
# This process should not return until the authorization passes.
# When it returns, $FKSH_HOM/authenticate.sh sends CONT signals
# to the processes stoped.
#
# The env var PATH starts with "/root/bin:${FKSH_HOM}/tools:"
# The env var TMPAUTHD is a temporary dir /tmp/A_XXXXXX
#
####

## set parameters
pwfile=$FKSH_ONB/passwd
[ -f "$pwfile" ] || exit 0
# defaults
authDelay=180      # on waked up, deley _180_ or no auth if _NAN_
emergencyTries=60  # _60_ fails before auth by microSD label and uuid
lowBat=12          # powerof if battery is less than _12_ %
mcsdKeys='/'
# decimal expressed number
sedDec='s/ +//g;/[^0-9]/q;s/^0+(.)/\1/;p;' # sed -n -r
#
wifiKeys='/'  ## TODO
while read -r v ; do
  v="${v%%#*}"; k="${v%%:*}"; v="${v#*:}"
  case "$k" in
  [Pp]ass[Ww]*)
    # at most 12 digits without same adjacent digits
    passwd="$(printf '%s' "$v" |
        sed -r 's/[^0-9]//g;s/(.)\1\1*/\1/g;s/^(.{12}).*/\1/' )"
  ;;
  [Aa]uth[Dd]*)
    authDelay="$(printf '%s' "$v" | sed -n -r "$sedDec" )"
  ;;
  [Ee][Mm]*[Tt]*)
    emergencyTries="$(printf '%s' "$v" | sed -n -r "$sedDec" )"
    [ -z "$emergencyTries" ] && emergencyTries=0
  ;;
  [Ss][Ll]*[Aa][Gg]*)
    sleepAgain="$(printf '%s' "$v" | sed -n -r "$sedDec" )"
  ;;
  [Mm]*[Cc]*[Ss][Dd][Kk][Ee][Yy]*)
    mcsdKeys="$mcsdKeys$(printf '%s' "$v" | sed 's/[^-,\.0-9A-Za-z_]//g' )/"
  ;;
  [Ll]ow*)
    lowBat="$(printf '%s' "$v" | sed -n -r "$sedDec" )"
    [ -z "$lowBat" ] && lowBat=0
    [ $lowBat -gt 75 ] && lowBat=75
  ;;
  esac
done >/dev/null < $pwfile
[ -z "$sleepAgain" ] && sleepAgain=30    # sleep again if _30_ secs idle
[ $sleepAgain -lt 5 ] && sleepAgain=5

toLOG () {
  [ -f "$FKSH_LOG" ] || return 0
  printf '%s %s\n' $(hwtime.sh) "$1" >> $FKSH_LOG
}

battLvl=100
battCheck () {
  local l
  while read l ; do
    case "$l" in
    'POWER_SUPPLY_VOLTAGE_NOW='*) b="${l#*=}" ; battLvl="$b" ;;
    'POWER_SUPPLY_STATUS=Charging') b=100 ; break ;;
    esac
  done </sys/class/power_supply/mc13892_bat/uevent
  [ -z "$b" ] && b=100
  if [ $b -lt $lowBat ] ; then
    toLOG "#POWEROFF lowBatt=$b"
    dispPics.sh -i poweroff.seq
    poweroff -f
  fi
}

sedMcSD='\@^/dev/mmcblk1p1:@{
s/^.*L="//;
s/"[^"]*"/,/;
s/".*$//;
s/[^-,\.0-9A-Za-z_]//g;
p;q;}'

## 1st call. send password

battCheck >/dev/null
if [ -z "$KOBO_passwd" ] ; then
  if [ -n "$1" ] ; then
    # on waked up
    [ -z "$authDelay" ] && exit 0
    [ $1 -lt $authDelay ] && exit 0
  fi
  # by wifi ap ssid and bssid (TODO)
  if [ $emergencyTries -eq 0 ] ; then
    mcSDid="$(blkid </dev/null| sed -n "$sedMcSD")"
    if [ -n "$mcSDid" ] ; then
      case "$mcsdKeys" in
      /) # Register 1st microSDkey
        printf '\nmicroSDkey: %s\n' "$mcSDid" >> $pwfile
        exit 0
      ;;
      */"$mcSDid"/*) # SUCC by microSDkey
        exit 0
      ;;
      esac
    fi
  fi
  printf "$passwd"  # never contains "%"
  exit 0
fi

## 2nd call. authorization

[ -d "$TMPAUTHD" ] || exit 0
[ $emergencyTries -eq 0 ] && emergencyTries=1

wnkCyc=$TMPAUTHD/wnkCyc
printf '5 0 8 8\n490 0 0 0\n' > $wnkCyc
whinker.sh $wnkCyc

eval $(fbset | awk '$1=="geometry"{ printf "w=%d;h=%d;bpp=%d;", $2, $3, $6;}')

timerfile=$TMPAUTHD/timer
# sleep again timer
{
  for pid in $(pidof fickel udhcpc wpa_supplicant ntpd) ; do exit 0 ; done
  touch $timerfile
  while : ; do
    [ -f $timerfile ] || exit
    slp=$(($(date +%s -r $timerfile) + $sleepAgain - $(date +%s) ))
    if [ $slp -le 0 ] ; then
      battCheck >/dev/null
      toLOG "#SLEEP_in_auth batt=$battLvl"
      echo "Sleep"
      dispPics.sh -i sleep.seq
      echo 1 > /sys/power/state-extended
      echo mem > /sys/power/state
      battCheck >/dev/null
      toLOG "#WAKED_UP batt=$battLvl"
      echo "Waked_up"
      dispPics.sh -i passwd.seq
      touch $timerfile
    else
      sleep $slp
    fi
  done
} &

# flash_seq
fbset -depth 16
flash_seq=$TMPAUTHD/flash.seq
cat > $flash_seq <<'EOflash_seq'
allWhite.raw.gz
150
allBlack.raw.gz
allWhite.raw.gz
allBlack.raw.gz
allWhite.raw.gz
EOflash_seq

# awk script
awkscr="BEGIN{
  h=$h; w=$w;"'
  ii=99;
  ib="@@@@@@@@@@@@"
}
$5==3{
  if ($6==0) {x=$7; next;}
  if ($6==1) {y=$7; next;}
  next;
}
$5==0{next;}
{i=9-3*int(4*x/w)-int(3*y/h);}
i==0||i==-1{
  printf "ib='%s';x=%d;y=%d;", ib, x, y;
  exit 0;
}
i<0{i=0;}
i==ii{next;}
{
  ii=i;
  ib=substr(ib i, 2);
}'

tries=$emergencyTries

dispPics.sh -i passwd.seq
forKill_od=$TMPAUTHD/forKill_od # not smart, how to re-valid SIGPIPE?
x=-1; y=-1
od -v -A n -t u2 --width=16 /dev/input/event1 2>$forKill_od | { while : ; do
  eval $(awk -v x=$x -v y=$y "$awkscr")
  touch $timerfile
  battCheck >/dev/null
  case $ib in
  *$KOBO_passwd)
    echo SUCC;
    break
  ;;
  *@??)
    # input must be more than two digits
    tries=$((tries-1))
    [ $tries -gt 0 ] && continue
    tries=$emergencyTries
    # emergency microSD auth
    mcSDid="$(blkid </dev/null| sed -n "$sedMcSD")"
    [ -z "$mcSDid" ] && continue
    case "$mcsdKeys" in
    /)
      echo 'Register 1st microSDkey'
      printf '\nmicroSDkey: %s\n' "$mcSDid" >> $pwfile
    ;;
    */"$mcSDid"/*) echo 'SUCC by microSDkey' ;;
    *) echo 'FAIL by microSDkey' ; continue ;;
    esac
    break
  ;;
  esac
  tries=$emergencyTries
  echo "FAIL: $ib"
  dispPics.sh -i passwd.seq
done
rm -f $timerfile
printf '60 8 0 0\n60 0 8 0\n60 0 0 8\n' > $wnkCyc
dispPics.sh -i $flash_seq
fuser -s -k -TERM $forKill_od # not smart, how to re-valid SIGPIPE?
exit 0
}
exit 0
