#!/usr/bin/perl

use strict;
use warnings;
use FindBin qw( $Bin );
use lib "$Bin/../../lib";
use POSIX qw( strftime );
use Data::Dumper;
use Date::Calc qw( Days_in_Month );
use JSON::XS;
use App::POS::Config;
use Email::Send::SMTP::Gmail;

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

my $LANG = $info->{LANG} || "";
$LANG = 'POS' if $LANG eq 'PT';
$LANG = 'SML' if $LANG eq 'AUDITOR';
my $DOC_TYPE_SERIE = $info->{DOC_TYPE_SERIE} || "";
my $SAFT_SEND_NETWORK = $info->{SAFT_SEND_NETWORK} || 0;
my $STATION_NUMBER = $info->{STATION_NUMBER} || 0;
my $SAFT_CompanyId = $info->{SAFT_CompanyId} || "";
my $SAFT_TaxRegistratioNumber = $info->{SAFT_TaxRegistratioNumber} || "";
my $SAFT_CompanyName = $info->{SAFT_CompanyName} || "";
my $SAFT_BusinessName = $info->{SAFT_BusinessName} || "";
my $SAFT_AddressDetail = $info->{SAFT_AddressDetail} || "";
my $SAFT_City = $info->{SAFT_City} || "";
my $SAFT_PostalCode = $info->{SAFT_PostalCode} || "";
my $SAFT_ZipXml = $info->{SAFT_ZipXml} || 0;
my $GENERATE_LOCALY = $info->{SAFT_GENERATE_LOCALY} || "";
my $INTERNET_GMAIL_LOGIN = $info->{INTERNET_GMAIL_LOGIN} || "";
my $INTERNET_GMAIL_PASSWORD = $info->{INTERNET_GMAIL_PASSWORD} || "";
my $INTERNET_SEND_MONTHLY_SAFT = $info->{INTERNET_SEND_MONTHLY_SAFT} || "";
my $INTERNET_SEND_EMAILS = $info->{INTERNET_SEND_EMAILS} || 0;
my $USE_NETBO = $info->{USE_NETBO} || 0;
$SAFT_SEND_NETWORK = $USE_NETBO if $USE_NETBO;

my $year_str = &strftime("%Y", localtime);
$DOC_TYPE_SERIE =~ s/\@YEAR\@/$year_str/g;
$DOC_TYPE_SERIE =~ s/\s//g;
$DOC_TYPE_SERIE =~ s/\///g;

my $MACHINE_ID = `/opt/pos/common/bin/machine_id`;
$MACHINE_ID =~ s/\n//g;
$MACHINE_ID =~ s/\r//g;
my $APP = "/opt/pos/common/addons/saft-pt/app.1.03";
my $DEST = "/tmp";

my $FROM = shift;
my $TO = shift;
my $FILE = shift;

if ($GENERATE_LOCALY && defined $FROM &&  $FROM eq 'LOCALFOLDER') {
  undef $FROM;
  my $a = &dates_guess();
  my $FROM = $a->[0];
  my $TO = $a->[1];

  if (! -d $GENERATE_LOCALY) {
    system("mkdir -p \"$GENERATE_LOCALY\"");
  }

  my $file = $SAFT_ZipXml ?
    "SAFT-PT#$SAFT_TaxRegistratioNumber#$FROM#$TO#$DOC_TYPE_SERIE.xml.zip" :
    "SAFT-PT#$SAFT_TaxRegistratioNumber#$FROM#$TO#$DOC_TYPE_SERIE.xml";

  my $full_path = $GENERATE_LOCALY . "/" . $file;

  if (! -e $full_path) {
    print STDERR "Will generate - $full_path\n";
    system("$APP $GENERATE_LOCALY $FROM $TO");
  }
  else {
    print STDERR "File $full_path exists, skipping...\n";
  }

  exit;
}

if ($STATION_NUMBER ne '0') {
  die "ERROR: THIS IS A STATION, CAN'T RUN ON STATIONS......\n";
}

if ($SAFT_SEND_NETWORK ne '1' && ! $INTERNET_SEND_MONTHLY_SAFT) {
  die "ERROR: SAFT_SEND_NETWORK AND INTERNET_SEND_MONTHLY_SAFT IS OFF IN config.ini...\n";
}

if ($MACHINE_ID =~ /^MAC/) {
  die "ERROR: HARDLOCK IS MISSING, ABORTING...\n";
}

my $of;
my $ot;
my $file_to_send = "";

if (defined $FROM && defined $TO) {
  # send a pre-generated file
  if (defined $FILE) {
    $file_to_send = $FILE;
  }
  # generate a file
  else {
    $of = $FROM;
    $ot = $TO;

    if ($SAFT_ZipXml) {
      unlink "/tmp/SAFT-PT#$SAFT_TaxRegistratioNumber#$of#$ot#$DOC_TYPE_SERIE.xml.zip";

      if (! check_synced($FROM)) {
        system("$APP $DEST $FROM $TO");
      }
      else {
        print STDERR "Synced already - $FROM - aborting...\n";
        exit;
      }

      $file_to_send = "/tmp/SAFT-PT#$SAFT_TaxRegistratioNumber#$of#$ot#$DOC_TYPE_SERIE.xml.zip";
    }
    else {
      unlink "/tmp/SAFT-PT#$SAFT_TaxRegistratioNumber#$of#$ot#$DOC_TYPE_SERIE.xml";

      if (! check_synced($FROM)) {
        system("$APP $DEST $FROM $TO");
      }
      else {
        print STDERR "Synced already - $FROM - aborting...\n";
        exit;
      }

      $file_to_send = "/tmp/SAFT-PT#$SAFT_TaxRegistratioNumber#$of#$ot#$DOC_TYPE_SERIE.xml";
    }
  }
}
else {
  my $a = &dates_guess();
  $FROM = $a->[0];
  $TO = $a->[1];
  #$FROM = '2012-12-01';
  #$TO = '2012-12-31';

  $of = $FROM;
  $ot = $TO;


  if ($SAFT_ZipXml) {
    unlink "/tmp/SAFT-PT#$SAFT_TaxRegistratioNumber#$of#$ot#$DOC_TYPE_SERIE.xml.zip";

    if (! check_synced($FROM)) {
      system("$APP $DEST $FROM $TO");
    }
    else {
      print STDERR "Synced already - $FROM - aborting...\n";
      exit;
    }

    $file_to_send = "/tmp/SAFT-PT#$SAFT_TaxRegistratioNumber#$of#$ot#$DOC_TYPE_SERIE.xml.zip";
  }
  else {
    unlink "/tmp/SAFT-PT#$SAFT_TaxRegistratioNumber#$of#$ot#$DOC_TYPE_SERIE.xml";

    if (! check_synced($FROM)) {
      system("$APP $DEST $FROM $TO");
    }
    else {
      print STDERR "Synced already - $FROM - aborting...\n";
      exit;
    }

    $file_to_send = "/tmp/SAFT-PT#$SAFT_TaxRegistratioNumber#$of#$ot#$DOC_TYPE_SERIE.xml";
  }
}

if (defined $FROM && defined $TO && -e $file_to_send) {
  if ($file_to_send !~ /\.zip$/) {
    system("zip -j -q /tmp/SAFT-PT_".$FROM."_".$TO.".xml.zip $file_to_send");
    unlink($file_to_send);
    $file_to_send = "/tmp/SAFT-PT_".$FROM."_".$TO.".xml.zip";
  }

  if (-e $file_to_send) {
    my $file = $file_to_send;

    if (
      $INTERNET_GMAIL_LOGIN && $INTERNET_GMAIL_PASSWORD &&
      $INTERNET_SEND_MONTHLY_SAFT && $INTERNET_SEND_EMAILS
    ) {
      eval {
        print STDERR "WILL SEND SAFT BY EMAIL...\n";

        my $email_obj = Email::Send::SMTP::Gmail->new(
          -smtp => 'smtp.gmail.com',
          -login => $INTERNET_GMAIL_LOGIN,
          -pass => $INTERNET_GMAIL_PASSWORD,
        );

        my @attachments = ( $file_to_send );

        $email_obj->send(
          -to => $INTERNET_SEND_MONTHLY_SAFT,
          -subject=> "[$LANG SAF-T] $SAFT_TaxRegistratioNumber $FROM $TO",
          -body=> "$LANG\n====\n\nSAF-T $FROM -> $TO\n\n$SAFT_TaxRegistratioNumber\n".
            "$SAFT_CompanyName\n$SAFT_BusinessName\n$SAFT_AddressDetail\n".
            "$SAFT_PostalCode $SAFT_City",
          -attachments=>join(",", @attachments),
        );
      };

      if ($@) {
        die "Email sending error... - $@\n";
      }
      else {
        &mark_synced($FROM);
      }
    }

=pod
    if ($SAFT_SEND_NETWORK) {
      print STDERR "WILL SEND $file TO SERVER ($MACHINE_ID)...\n";

      my $server_files = `curl http://releases.ptcert.com/api/machines/saft/list_simple?machine_id=$MACHINE_ID 2> /dev/null`;
      my $exists_in_server = 0;
      my $file_to_check = "SAFT-PT_".$FROM."_".$TO.".xml.zip";

      if ($server_files) {
        my $files;
        eval { $files = decode_json($server_files); };

        if (defined $files) {
          # SAFT-PT_2012-12-01_2012-12-31.xml.zip
          for (@$files) {
            if ($file_to_check eq $_) {
              $exists_in_server = 1;
              last;
            }
          }
        }
      }

      if ($exists_in_server) {
        &mark_synced($FROM);
        die "SAFT FOR DATES $FROM TO $TO ALREADY EXISTS ON SERVER, ABORTING...\n";
      }

      my $res = `curl -F "SAFT_CompanyId=$SAFT_CompanyId" -F "SAFT_TaxRegistratioNumber=$SAFT_TaxRegistratioNumber" -F "SAFT_CompanyName=$SAFT_CompanyName" -F "SAFT_BusinessName=$SAFT_BusinessName" -F "SAFT_AddressDetail=$SAFT_AddressDetail" -F "SAFT_City=$SAFT_City" -F "SAFT_PostalCode=$SAFT_PostalCode" -F "machine_id=$MACHINE_ID" -F "fileupload=\@$file" http://releases.ptcert.com/api/machines/file_receive`;

      if ($res ne 'OK') {
        print $res;
        die "ERROR: COULDN'T POST FILE $file TO SERVER...\n";
      }
      else {
        &mark_synced($FROM);
        #unlink($file);
      }
    }
=cut
  }
  else {
    die "ERROR: /tmp/saft_".$FROM."__".$TO.".zip IS MISSING, ABORTING...\n";
  }
}
else {
  die "ERROR: SAF-T FILE WASN'T GENERATED, ABORTING...\n";
}

sub dates_guess {
  my $y = &strftime("%Y", localtime);
  my $m = &strftime("%m", localtime);

  if ($m eq '01') {
    $m = 12;
    $y--;
  }
  else {
    $m = $m*1;
    $m = sprintf("%02d", --$m);
  }

  my $days = Days_in_Month($y,$m);
  return [ "$y-$m-01", "$y-$m-$days" ];
}

sub check_synced {
  my $date_str = shift;
  my( $year, $month ) = $date_str =~ /^(\d\d\d\d)\-(\d\d)\-/;

  if (-e "/opt/pos/common/data/saft_to_network/$year/$month.txt") {
    return 1;
  }
  else {
    return 0;
  }
}

sub mark_synced {
  my $date_str = shift;
  my( $year, $month ) = $date_str =~ /^(\d\d\d\d)\-(\d\d)\-/;

  system("mkdir -p /opt/pos/common/data/saft_to_network/$year")
    unless -d "/opt/pos/common/data/saft_to_network/$year";

  open(F, "> /opt/pos/common/data/saft_to_network/$year/$month.txt");
  print F "1\n";
  close(F);
}

