#!/usr/bin/perl

use strict;
use warnings;

my $study_temp;
my $current_state;
my $user_inhibit;
my $user_request;
my $timer_operating;
my $current_thermo_state;
my $mode;
my $mode_str;
my $current_thermostat;
my $ac_has_been_automatically_enabled;

sub println {
  print @_;
  print "\n";
}

# behave as linux touch/cat command to create empty file or file with content, with error checking
sub touch {
  my ($filename, $content) = (@_);
  open(FH, ">$filename") or die "can't open $filename for write";
  print FH "$content\n" if defined $content;
  close FH or die "can't close $filename for write";
}

# Read the file and insert the chomp()ed result into an array
sub readfile {
  my ($filename,$ignore_error) = (@_);
  if (!open(FH, "$filename")) {
    die "can't open $filename for read" if !$ignore_error;
    #    return undef;
    return ();
  }
  my @content=<FH>;
  chomp @content;
  close FH;
  return @content;
}

sub fetch_current_state {
  my ($silent) = (@_);
  $study_temp=(readfile "/tmp/study_temp")[0];
  ($current_state)=split(' ', (readfile "/tmp/ac.state")[0]);
  ($user_inhibit)=split(' ', (readfile "/var/tmp/ac.state_timeroverride")[0]);
  ($user_request)=split(' ', (readfile "/var/tmp/ac.state_desired")[0]);
  ($timer_operating)=(grep (/(after|until)/, (readfile "/var/tmp/ac.state_timeroverride")), "0");
#  if ($timer_operating =~ s/(enable after|disable until).*#//) {
#    $current_state="$current_state (on timer $timer_operating)<BR>";
#  } elsif ($timer_operating =~ s/(disable after|enable until).*#//) {
#    $current_state="$current_state (off timer $timer_operating)<BR>";
#  }
  ($current_thermo_state)=split(' ', (readfile "/tmp/ac.state_thermo")[0]);
  ($mode)=split(' ', (readfile "/var/tmp/ac_mode")[0]);
  if ($mode eq "ac") {
    $mode_str="Air conditioner"
  } else {
    $mode_str="Heater";
  }

  ($current_thermostat)=split(' ', (readfile "/var/tmp/ac.thermostat.$mode")[0]);
  $ac_has_been_automatically_enabled=-e "/var/tmp/ac.ac_has_been_automatically_enabled" ? 1 : 0;

  if (!$silent) {
    println "study_temp=$study_temp";
    println "current_state=$current_state";
    println "user_inhibit=$user_inhibit";
    println "user_request=$user_request";
    println "timer_operating=$timer_operating";
    println "current_thermo_state=$current_thermo_state";
    println "mode=$mode";
    println "current_thermostat=$current_thermostat";
    println "ac_has_been_automatically_enabled=$ac_has_been_automatically_enabled";
  }
}

sub enable {
  if ($ac_has_been_automatically_enabled) {
    println "AC has already been enabled once.  Let the user decide from here";
  } else {
    println "Will enable $mode_str";
    system("request_on_ac ; ${mode}_enable ; touch /var/tmp/ac.ac_has_been_automatically_enabled");
  }
}

sub request_off_ac {
  system("request_off_ac");
}

sub request_on_ac {
  system("request_on_ac");
}

sub enable_and_ramp_if_not_inhibited {
  my ($homezone, $ramping)=(@_);
  if (!$timer_operating) {
#    if ($mode eq "ac") {
#      # In AC mode, don't start ramping when we start nearing home.
#      # Instead only start the ramp the moment we hit the homezone
#      if (!$homezone) {
#        unlink "/var/tmp/ac.inhomezone";
#      } else {
#        if (! -e "/var/tmp/ac.inhomezone") {
#          system("touch /var/tmp/ac.inhomezone");
#          if ($ramping) {
#            system("date +%s > /var/tmp/ac.state_rampup");  # we've just entered homezone.  Set the ramp once
#          } else {
#            system("echo 0 > /var/tmp/ac.state_rampup");
#          }
#        }
#      }
#    } else {
      if (!$homezone) {  # In heat mode, set the ramp straight away
                         # when we're nearing home, so temperature
                         # setpoint is always low, until the moment we
                         # hit the homezone, whereup the ramp starts
                         # increasing towards setpoint
        if ($ramping) {
          system("date +%s > /var/tmp/ac.state_rampup");
        } else {
          system("echo 0 > /var/tmp/ac.state_rampup");
        }
        println ($ramping ? "Ramping temperature" : "Not ramping temperature");
      }
#    }
    enable;
  } else {
    println "Not enabling AC since was previously on an override timer";
  }
}

sub disable {
  if (!$ac_has_been_automatically_enabled) {
    println "AC has already been disabled once.  Let the user decide from here";
  } else {
    println "Will disable $mode_str";
    system("${mode}_disable ; rm -f /var/tmp/ac.ac_has_been_automatically_enabled");
# clear any "disable after" state
  }
}

sub disable_if_not_inhibited {
  if (!$timer_operating) {
    disable;
  } else {
    println "Not disabling AC since was previously on an override timer";
  }
}

sub usage {
  print STDERR "Usage: handle_remote_ac gather_ac_facts|enable|disable|enable_and_ramp_if_not_inhibited homezone ramping |disable_if_not_inhibited\n";
  exit 1;
}

if (!defined $ENV{SSH_ORIGINAL_COMMAND}) {
  usage;
}
my $command = $ENV{SSH_ORIGINAL_COMMAND};
@ARGV=split(" ", $command);

if (@ARGV < 2) {
  usage;
}

if ($ARGV[0] ne "handle_remote_ac") {
  usage;
} else {
  shift @ARGV;
}

if ($ARGV[0] eq "gather_ac_facts") {
  fetch_current_state;
  exit 0;
} else {
  fetch_current_state "silent";
}

if ($ARGV[0] eq "enable") {
  enable;
} elsif ($ARGV[0] eq "disable") {
  disable;
} elsif ($ARGV[0] eq "enable_and_ramp_if_not_inhibited") {
  if (@ARGV != 3) {
    usage;
  }
  my ($homezone, $ramping)=($ARGV[1], $ARGV[2]);
  enable_and_ramp_if_not_inhibited ($homezone,$ramping);
} elsif ($ARGV[0] eq "disable_if_not_inhibited") {
  disable_if_not_inhibited;
} elsif ($ARGV[0] eq "request_on_ac") {
  request_on_ac;
} elsif ($ARGV[0] eq "request_off_ac") {
  request_off_ac;
} else {
  usage;
}

