#!/usr/bin/perl

use Modem::VBox;
use Sys::Syslog;

$SIG{HUP} = 'IGNORE';

sub send_file {
   my ($subject, $filename, $mailto) = @_;
   if (fork == 0) {
      require POSIX;
      require MIME::Entity;

      $top = MIME::Entity->build(Type    =>"multipart/mixed",
                                 From    => "vbox\@plan9.de",
                                 To      => $mailto,
                                 Subject => $subject);

      $top->attach(
         Path        => $filename,
         Type        => "application/vbox",
         Encoding    => "base64",
      );

      open MAIL, "| /usr/sbin/exim -t -oi -oem" or die "open: $!";
      $top->print(\*MAIL);
      close MAIL;
      POSIX::_exit(0);
   }
}

#{
#   require NetServer::ProcessTop;
#   NetServer::ProcessTop->new(7000);
#};

Sys::Syslog::setlogsock "unix";
openlog "vbox", "cons,ndelay", "user";

$|=1;

$vaheader_p = "A4 N N a33 a33 a33 a65 a33 a33 a65 a65 a33 a33 a65 a65";

$BASE="/var/spool/vbox";
$MSG="$BASE/messages";
$INC="$BASE/incoming";

$SIG{CHLD} = 'IGNORE';

sub num { sprintf "$MSG/_%d", shift }
sub msg { "$MSG/$_[0]" }

$v = new Modem::VBox
   line => $ARGV[0] || "/dev/ttyI1",
   modeminit => 'ATZ&D2&B512&E9377358S13.4=0S13.2=1S13.6=0+FCLASS=8',
   rings => 5, # connect after 5 rings
   connect_cb => \&main_menu,
   ring_cb => sub {
      my ($count, $cid) = @_;
      my ($name, $avon);
      if ($count == 1) {
         fork == 0 and do { exec "/etc/rc.spinup"; exit };
         open PHONE, "</var/spool/vbox/phone" and do {
            my $pm = qr/^$cid\s+(.*)/;
            while(<PHONE>) {
               if (/$pm/) {
                  $name = $1;
                  last;
               }
            }
            close PHONE;
         };
         $cid =~ s/^([^0])/49$1/;
         open AVON, "</var/spool/vbox/avon" and do {
            my $pm = join "|", map { substr $cid, 0, $_, } 2..length $cid;
            $pm = qr/^(?:$pm):(.*)$/;
            while(<AVON>) {
               if (/$pm/) {
                  $avon = $1;
                  last;
               }
            }
            close AVON;
         };
         $v->{phone} = $cid;
         $v->{avon}  = $avon;
         $v->{name}  = $name;
         system "DISPLAY=cerebro:0 exec /usr/X11/bin/xmessage -default 'okay' -nearmouse -timeout 60 '$cid\n$name\n$avon' &";
         syslog "notice", "RING: $cid $name ($avon)";
      }
   };

$v->loop;

sub not_valid {
   my $context = $v->context->set(".*" => sub {});
   $v->play_flush;
   $v->play_file (msg ("number_not_valid"));
   $v->play_pause (0.4);
   $v->play_drain;
}

sub record_menu {
   my $context = $v->context->clr;
   $v->play_file("$MSG/record");
   my $msgtime = time;
   my $savename = sprintf "$INC/%14.14lu-%8.8lu", $msgtime, $$;
   while(my $ev = $v->event) {
      if ($ev->iseotx(0)) {
         my $va = pack $vaheader_p,
                       "VBOX",
                       $msgtime,
                       6,
                       $v->callerid,
                       $v->{name},
                       $v->{phone},
                       "**location**",
                       "", "",
                       "", "";

         syslog "notice", "MESG+ %s %s (%s)", $v->{phone}, $v->{name}, $v->{avon};

         open FILE, ">$savename" or die "unable to create $savename: $!";
         print FILE $va;
         $v->play_drain;
         $v->record_file (*FILE);
         do { } while $v->event;
         close FILE;

         send_file("MESG $v->{phone}=$v->{name} ($v->{avon})", $savename, "root\@plan9.de");
         syslog "notice", "MESG- %s %s (%s)", $v->{phone}, $v->{name}, $v->{avon};
         return;
      }
   }
}

sub music_menu {
   my $context = $v->context->set(
         "0\$" => 0,
   );
   $v->play_file("$MSG/nyi"); $v->play_pause(1);
   for(;;) {
      my $i = 1;
      for (
            [sailormoon		=> "sailormoon"],
            [shampoo		=> "shampoo"],
            [evangelion		=> "evangelion"],
            [xcgs		=> "xcgs"],
            [akira_shohmyoh	=> "shohmyoh"],
            [why_cooperation	=> "why_cooperation"],
          ) {
         my ($t,$s)=@$_;
         $v->play_file (num ($i)); $v->play_pause (0.15);
         $v->play_file (msg ($t)); $v->play_pause (0.75);
         $context->add("$i\$" => sub {
            $v->play_flush;
            $v->play_file (msg ("song_$s"));
            $v->play_pause (1)
         });
         $i++;
      }
      while (my $ev = $v->event) {
         if ($ev->iseotx(0)) {
            last;
         } elsif ($ev->isbreak("0")) {
            $v->play_flush;
            return;
         }
      }
   }
}

sub main_menu {
   my $context = $v->context->set(
      "1\$" => [\&record_menu],
      "2\$" => [\&music_menu],
      "[^12]+\$" => \&not_valid,
   );
   my $event;
   $v->play_file("$MSG/welcome"); $v->play_pause(0.2);
   while (my $ev = $v->event) {
      if ($ev->isbreak) {
         $v->play_flush;
         $v->play_pause(0.5);
         $ev->data->[0]->();
         return unless $v->connected;
      }
      
      if ($v->play_count <= 1) {
         $v->play_file("$MSG/help");
         $v->play_pause(1);
      }
   }
}

