package ticketserver::registration;

use warnings;
use strict;
use POE qw( Wheel::Run );
use ADBGUI::BasicVariables qw($DEBUG $INFO $WARNING);
use ADBGUI::Tools qw(Log);

my $RESTARTINTERVAL = 5;

sub new {
   my $proto = shift;
   my $class = ref($proto) || $proto;
   my $config = shift;
   my $curconfig = shift;
   my $self = {};
   bless ($self, $class);
   $self->{config} = $config;
   $self->{session} = POE::Session->create(
      inline_states => {
         _start           => \&on_start,
         got_child_stdout => \&on_child_stdout,
         got_child_stderr => \&on_child_stderr,
         got_child_close  => \&on_child_close,
         got_child_signal => \&on_child_signal,
         start_tcpdump    => \&start_tcpdump,
      },
      args => [$self, $curconfig],
   );
   return $self;
}

sub on_start {
   my ($self, $config, $heap, $kernel) = @_[ARG0, ARG1, HEAP, KERNEL];
   $heap->{self} = $self;
   $self->{myconfig} = $config;
   Log("Starting tcpdump for ".$config->{apname}, $DEBUG);
   $kernel->yield("start_tcpdump");
}

sub start_tcpdump {
   my ($kernel, $heap) = @_[KERNEL, HEAP];
   Log("Connecting to ".$heap->{self}->{myconfig}->{apip}." for monitoring interface ".$heap->{self}->{myconfig}->{apwlanif}, $INFO);
   $heap->{self}->{child} = POE::Wheel::Run->new(
      NoSetSid => 1,
      NoSetPgrp => 1,
      Program => [ "/usr/bin/ssh -o ServerAliveInterval=300 -o TCPKeepAlive=yes -o ServerAliveInterval=15 -i ".$heap->{self}->{myconfig}->{apsshkey}." -T ".$heap->{self}->{myconfig}->{apip}." tcpdump -i ".$heap->{self}->{myconfig}->{apwlanif}." -n -e -l inbound" ],
      StdoutEvent  => "got_child_stdout",
      StderrEvent  => "got_child_stderr",
      CloseEvent   => "got_child_close",
   );
   #return $_[KERNEL]->yield(got_child_stdout => '14:18:33.214750 18:87:96:87:b6:48 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 369: 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 18:87:96:87:b6:48, length 327');
   $_[KERNEL]->sig_child($heap->{self}->{child}->PID, "got_child_signal");
   $_[HEAP]{children_by_wid}{$heap->{self}->{child}->ID} = $heap->{self}->{child};
   $_[HEAP]{children_by_pid}{$heap->{self}->{child}->PID} = $heap->{self}->{child};
   Log("Child pid ".$heap->{self}->{child}->PID." started as wheel ".$heap->{self}->{child}->ID, $INFO);
}

sub on_child_stdout {
   my ($stdout_line, $wheel_id, $heap) = @_[ARG0, ARG1, HEAP];
   my $child = $heap->{children_by_wid}->{$wheel_id};
   #print "pid ", $child->PID, " STDOUT: $stdout_line\n";
   if ($stdout_line =~ m/^(\d{1,2}\:){2}\d{1,2}\.\d+\ (([\da-f]{2}\:){5}[\da-f]{2})\ \>\ ff\:ff\:ff\:ff\:ff\:ff/) {
      my $mac = $2;
      $mac =~ s,\:,,g;
      $heap->{self}->{active}->{uc($mac)} = [time(), $heap->{self}->{myconfig}->{apwlanif}, $heap->{self}->{myconfig}->{apname}];
      Log("Found: ".$mac, $DEBUG);
   #} else {
   #   print "\tNOOO:".substr($stdout_line, 0, 20)."\n";
   }
}

sub on_child_stderr {
   my ($stderr_line, $wheel_id) = @_[ARG0, ARG1];
   my $child = $_[HEAP]{children_by_wid}{$wheel_id};
   Log("pid ".($child ? $child->PID : "-")." STDERR: $stderr_line", $INFO);
}

sub on_child_close {
   my $wheel_id = $_[ARG0];
   my $child = delete $_[HEAP]{children_by_wid}{$wheel_id};

   # May have been reaped by on_child_signal().
   unless (defined $child) {
      Log("wid $wheel_id closed all pipes.", $WARNING);
      return;
   }
   Log("pid ".$child->PID." closed all pipes.", $WARNING);
   delete $_[HEAP]{children_by_pid}{$child->PID};
}

sub on_child_signal {
  Log("pid $_[ARG1] exited with status $_[ARG2]", $WARNING);
  my $child = delete $_[HEAP]{children_by_pid}{$_[ARG1]};

  $poe_kernel->delay("start_tcpdump" => $RESTARTINTERVAL);

  # May have been reaped by on_child_close().
  return unless defined $child;

  delete $_[HEAP]{children_by_wid}{$child->ID};
}
