#!/usr/bin/perl

use strict;
use warnings;
use FindBin qw( $Bin );
use lib "$Bin/../../lib";
use Data::Dumper;
use App::POS::Config;
use App::POS::Machine::Server;
use UUID::Tiny;
use File::Copy qw( copy );

my $dates = shift;
die "Usage: $0 <date1,date2,...>\n" unless defined $dates;

my $cfg = App::POS::Config->new( file => "/opt/pos/etc/config.ini" );
my $info = $cfg->load_fixed();

my $machine = undef;

if (exists $info->{STATION_NUMBER} && $info->{STATION_NUMBER} == 0) {
  $machine = App::POS::Machine::Server->new( config => $cfg );  
} else {
  die "Needs to be executed in the server machine...\n";
}

my $machine_id=`/opt/pos/common/bin/machine_id`;
my $db = $machine->database();
my $dbh = $db->dbh();

my @dates = ();

if ($dates eq 'all') {
  my $r = $db->select("SELECT DISTINCT(business_date) AS date FROM sales_headers");
  map { push @dates, $_->{date} } @$r;
}
else {
  @dates = split /,/, $dates;
}

foreach my $date (@dates) {
  my $rand = &create_UUID_as_string();
  my $f1_tmp = $Bin."/".$rand;
  my $f1 = $machine->dir_replicate_network()."/#db#".$rand;
  my $table_fields = &_table_fields($machine, 'sales_details');
  my $query = &_build_insert_str('sales_details', $table_fields);

  my $sth = $dbh->prepare(qq{
    SELECT sd.*
    FROM sales_details sd
    LEFT JOIN sales_headers sh ON (sh.id = sd.header)
    WHERE sh.business_date = ?
  });

  $sth->execute($date);

  open(F, ">> $f1_tmp") or die "Can't write to $f1_tmp - $!";
  print F "REIMPORT=$date§$machine_id;".$query."\n\t\n";

  while (my $row = $sth->fetchrow_arrayref()) {
    print F join("#", @$row)."\n";
  }

  close(F);
  &copy( $f1_tmp, $f1 );
  unlink($f1_tmp);

  $rand = &create_UUID_as_string();
  $f1_tmp = $Bin."/".$rand;
  $f1 = $machine->dir_replicate_network()."/#db#".$rand;
  $table_fields = &_table_fields($machine, 'sales_payments');
  $query = &_build_insert_str('sales_payments', $table_fields);

  $sth = $dbh->prepare(qq{
    SELECT sd.*
    FROM sales_payments sd
    LEFT JOIN sales_headers sh ON (sh.id = sd.header)
    WHERE sh.business_date = ?
  });

  $sth->execute($date);

  open(F, ">> $f1_tmp") or die "Can't write to $f1_tmp - $!";
  print F "REIMPORT=$date§$machine_id;".$query."\n\t\n";

  while (my $row = $sth->fetchrow_arrayref()) {
    print F join("#", @$row)."\n";
  }

  close(F);
  &copy( $f1_tmp, $f1 );
  unlink($f1_tmp);

  $rand = &create_UUID_as_string();
  $f1_tmp = $Bin."/".$rand;
  $f1 = $machine->dir_replicate_network()."/#db#".$rand;
  $table_fields = &_table_fields($machine, 'sales_headers');
  $query = &_build_insert_str('sales_headers', $table_fields);

  $sth = $dbh->prepare(qq{
    SELECT *
    FROM sales_headers
    WHERE business_date = ?
  });

  $sth->execute($date);

  open(F, ">> $f1_tmp") or die "Can't write to $f1_tmp - $!";
  print F "REIMPORT=$date§$machine_id;".$query."\n\t\n";

  while (my $row = $sth->fetchrow_arrayref()) {
    $row->[-1] = "" unless defined $row->[-1];
    print F join("#", @$row)."\n";
  }

  close(F);
  &copy( $f1_tmp, $f1 );
  unlink($f1_tmp);
}

sub _table_fields {
  my( $machine, $table_name ) = @_;

  my $db = $machine->database();

  my @ff = ();

  my $recs = $db->select("SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$table_name' ORDER BY ordinal_position");

  for (@$recs) {
    push @ff, $_->{column_name};
  }

=pod
  my $f = $machine->file_database();

  my $tables = `sqlite3 $f ".tables"`;
  $tables =~ s/\s+/,/g;
  $tables =~ s/,$//;

  my @tables = split /,/, $tables;

  foreach my $table (@tables) {
    next unless $table eq $table_name;
    my @fields = `sqlite3 $f ".schema $table"`;

    foreach my $f (@fields) {
      if ($f =~ /^\s/) {
        chop($f);
        my( $name ) = $f =~ /^\s+(\w+)\s/;
        if ($name ne 'UNIQUE') {
          push @ff, $name;
        }
      }
    }
  }
=cut

  return \@ff;
}

sub _build_insert_str {
  my( $table, $fields ) = @_;

  my $q = "INSERT INTO $table (";

  foreach my $field (@$fields) {
    $q .= "$field, ";
  }

  $q =~ s/, $/) VALUES (/;

  foreach my $field (@$fields) {
    $q .= "?, ";
  }

  $q =~ s/, $/)/;

  return $q;
}

