#!/usr/bin/perl

##
# by Thomas Koch <tom@linvdr.org>
##
use POSIX qw(strftime sprintf);
use Time::Local;

my $PROC_ALARM = "/proc/acpi/alarm";
my $SETTIME = "/usr/bin/settime.sh";
my $DEBUG = 0;
my $WAKEUP_MARGIN = 5;
my $TWOOCLOCK = 0;
my $METHOD = 0;         # 0 = ACPI-Wakeup, 1 = settime

sub true() { 1; }
sub false() { 0; }

sub dprint {
  $_ = join("", @_);
  chomp;
  print "$_\n" if($DEBUG);
}

sub setTime {
  system("hwclock -w"); 
  #system("hwclock -w --directisa");
}  

sub setAlarm {
  my $Next = shift;
  my $TwoOclock = NextTwoOclock();
  my $NextStart; 
  my $ShouldStart;
  setTime();  
  
  if($Next) {
    if($Next > $TwoOclock) {
      $ShouldStart = true;
    }
    $NextStart = $Next - ($WAKEUP_MARGIN * 60);
    dprint("Next event at ", strftime("%d.%m.%Y %H:%M", localtime($Next)));
  } else {
    $ShouldStart = true; 
  }

  if($TWOOCLOCK && $ShouldStart) {
    $NextStart = $TwoOclock;
  }
  
  if($NextStart) {
    dprint("Programming wakeup at ", strftime("%d.%m.%Y %H:%M:%S", localtime($NextStart)));
    if($METHOD == 0) {
      if(-e $PROC_ALARM) {
        system(sprintf("echo \"%s\" > %s", strftime("%Y-%m-%d %H:%M", localtime($NextStart)), $PROC_ALARM));
      } else {
        dprint("$PROC_ALARM does not exist");
      }
    } else {
      if(-e $SETTIME) {
        system(sprintf("%s \"%s\"", $SETTIME, strftime("%Y-%m-%d %H:%M:00", localtime($NextStart))));
      } else {
        dprint("$SETTIME does not exist");
      }
    }
  }
}

sub PowerOff {
  system("/bin/busybox poweroff") if(!$DEBUG);
}

sub NextTwoOclock {
  my $now = time();
  # Array-Format: ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
  my @today = localtime($now);
  @today[0..2] = (0, 0, 2);

  # get today 2:00 in seconds since epoc
  my $TwoOclock = timelocal(@today);
  
  # Check: Is today 2:00 in future or past?
  if($now < $TwoOclock) {
    # Today two oclock is in future
    return $TwoOclock;
  } else {
    # We're past two oclock, next two oclock is tomorrow (+86400s)
    return $TwoOclock+86400;
  }
}

if(scalar(@ARGV)) {
  # called from vdr
  die "Wrong parameter count\n" if(scalar(@ARGV) != 5);
  die "$PROC_ALARM missing" if(!-e $PROC_ALARM);

  my($Next, $Delta, $Channel, $Recording, $UserShutdown) = @ARGV;
  
  setAlarm($Next);
  PowerOff();
} else {
  # called from cmdline
  $next = `svdrpsend.pl next abs`;
  if($next =~ /550 No active timers/) {
    setAlarm(0);
    PowerOff();
  } elsif($next =~ /250 \d+ (\d+)/) {
    setAlarm($1);
    PowerOff();
  } else {
    PowerOff();
  }
}	
