#!/usr/bin/perl -w

use strict;
use FS::Daemon ':all'; #daemonize1 drop_root daemonize2 myexit logfile sig*
use FS::UID qw( adminsuidsetup );
use FS::Record qw( qsearch ); #qsearchs);
#use FS::cdr;
use FS::cust_pkg;
use FS::queue;

my $user = shift or die &usage;

#daemonize1('freeside-sprepaidd', $user); #keep unique pid files w/multi installs
daemonize1('freeside-cdrd');

drop_root();

adminsuidsetup($user);

logfile( "%%%FREESIDE_LOG%%%/cdrd-log.". $FS::UID::datasrc );

daemonize2();

die "not running; no voip_cdr package defs w/ bill_every_call and customer pkgs"
  unless _shouldrun();

#--

my $addl_from =
  'LEFT JOIN part_pkg USING ( pkgpart ) '.
  "LEFT JOIN part_pkg_option
     ON ( cust_pkg.pkgpart = part_pkg_option.pkgpart
          AND part_pkg_option.optionname = 'bill_every_call' )";

#XXX should pay attention to disable_src for efficiency

my $extra_sql =
  "WHERE plan = 'voip_cdr' ".
  " AND optionvalue = '1' ".
  " AND ( susp   IS NULL OR susp   = 0)".
  " AND ( cancel IS NULL OR cancel = 0)".
  " AND 0 < ( 
      SELECT COUNT(*) FROM svc_phone LEFT JOIN cust_svc USING (svcnum)
        WHERE cust_pkg.pkgnum = cust_svc.pkgnum
          AND 0 < ( SELECT COUNT(*) FROM cdr
                      WHERE ( freesidestatus IS NULL OR freesidestatus = '' )
                        AND (    charged_party = svc_phone.phonenum
                              OR charged_party = svc_phone.countrycode
                                                 || svc_phone.phonenum
                              OR src = svc_phone.phonenum
                              OR src = svc_phone.countrycode
                                       || svc_phone.phonenum
                            )
                  )
    )
    AND 0 = (
      SELECT COUNT(*) FROM queue
        WHERE queue.job = 'FS::cust_main::queued_bill'
          AND queue.custnum = cust_pkg.custnum
    )
    
  ";
# don't repeatedly queue failures
#          AND status != 'failed'

while (1) {

  my $found = 0;
  foreach my $cust_pkg ( 
    qsearch( {
      'select'    => 'cust_pkg.*, part_pkg.plan',
      'table'     => 'cust_pkg',
      'addl_from' => $addl_from,
      'hashref'   => {},
      'extra_sql' => $extra_sql,
    } )
  ) {

    $found = 1;

    #my $work_cust_pkg = $cust_pkg;

    #my $cust_main = $cust_pkg->cust_main;

    my $time = time;

    my $job = new FS::queue {
      'job'     => 'FS::cust_main::queued_bill',
      'secure'  => 'Y',
      'custnum' => $cust_pkg->custnum,
    };
    my $error = $job->insert(
      'custnum'      => $cust_pkg->custnum, 
      'time'         => $time,
      'invoice_time' => $time,
      'actual_time'  => $time,
      'check_freq'   => '1d', #well
      #'debug'        => 1,
    );

    if ( $error ) {
      #die "FATAL: error inserting billing job: $error\n";
      warn "WARNING: error inserting billing job (will retry in 30 seconds):".
           " $error\n";
      sleep 30; #i dunno, wait and see if the database comes back?
    }

  }

  myexit() if sigterm() || sigint();
  sleep 1 unless $found;

}

#--

sub _shouldrun {

  my $extra_sql =
    ' AND 0 < ( SELECT COUNT(*) FROM cust_pkg
                  WHERE cust_pkg.pkgpart = part_pkg.pkgpart
                    AND ( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
              )
    ';

  my @part_pkg =
    grep $_->option('bill_every_call', 'hush'),
    qsearch({
      'table'     => 'part_pkg',
      'hashref'   => { 'plan' => 'voip_cdr' },
      'extra_sql' => $extra_sql,
    })
  ;

  scalar(@part_pkg);

}

sub usage { 
  die "Usage:\n\n  freeside-cdrd user\n";
}

=head1 NAME

freeside-cdrd - Real-time daemon for CDRs

=head1 SYNOPSIS

  freeside-cdrd

=head1 DESCRIPTION

Runs continuously, searches for CDRs and bills customers who have VoIP
price plands with the B<bill_every_call> option set.

=head1 SEE ALSO

=cut

1;