#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use WWW::Mechanize;
use Encode;
use JSON::XS qw( decode_json );
use Mozilla::CA;
use HTML::Entities;

my $nif = shift || "";

if (! $nif) {
  print ""."#".""."#".""."#"."";
  exit;
}

my $country = 'PT';

$nif =~ s/'//g;
$country =~ s/'//g;

my $url = 'https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number';
my $cmd = 'curl -s -X POST '.$url.' -H "Content-Type: application/json" -d \'{ "countryCode": "'.$country.'", "vatNumber": "'.$nif.'" }\'';

my $out = `$cmd`;
$out ||= "";

if (! $out) {
  my $nifpt = nif_pt($nif);
  if ($nifpt) {
    my $name = $nifpt->[0];
    my $address = '';
    my $postal_code = $nifpt->[2] || '';
    my $city = $nifpt->[1] || '';
    print encode("utf8", trim($name)."#".trim($address)."#".trim($city)."#".$postal_code);
    exit;
  }
  print ""."#".""."#".""."#"."";
  exit;
}

my $ref = {};

eval {
  $ref = decode_json($out);
};

if ($@) {
  my $nifpt = nif_pt($nif);
  if ($nifpt) {
    my $name = $nifpt->[0];
    my $address = '';
    my $postal_code = $nifpt->[2] || '';
    my $city = $nifpt->[1] || '';
    print encode("utf8", trim($name)."#".trim($address)."#".trim($city)."#".$postal_code);
    exit;
  }
  print ""."#".""."#".""."#"."";
  exit;
}

my $name = $ref->{name} || "";
my $address = $ref->{address} || "";
my $postal_code = "";
my $city = "";

if (! $name) {
  my $nifpt = nif_pt($nif);
  if ($nifpt) {
    $name = $nifpt->[0];
    $address = '';
    $postal_code = $nifpt->[2] || '';
    $city = $nifpt->[1] || '';
    print encode("utf8", trim($name)."#".trim($address)."#".trim($city)."#".$postal_code);
    exit;
  }
}

if ($address) {
  $address =~ s/\r//g;
  my @addr = split /\n/, $address;
  $postal_code = $addr[2];
  ( $postal_code ) = $postal_code =~ /^(.*?) /;
  $postal_code ||= "";
  $city = $addr[1] || "";
  $address = $addr[0] || "";
}

#print STDERR "#### #$name#\n";
#print STDERR "#### #$address#\n";
#print STDERR "#### #$city#\n";
#print STDERR "#### #$postal_code#\n";

print encode("utf8", trim($name)."#".trim($address)."#".trim($city)."#".$postal_code);

sub trim {
  my $w = shift;
  return $w unless defined $w && $w;
  $w =~ s/^\s+//;
  $w =~ s/\s+$//;
  return $w;
}

sub nif_pt {
  my $nif = shift;
  my $url = 'http://www.nif.pt';
  my $mech;

  $ENV{PERL_LWP_SSL_CA_FILE} = Mozilla::CA::SSL_ca_file();

  eval {
    $mech = WWW::Mechanize->new(
      timeout => 15,
      ssl_opts => {
        verify_hostname => 0,
      },
    );
    $mech->ssl_opts( 'verify_hostname' => 0 );
    $mech->get( $url );

    $mech->submit_form(
      form_number => 1,
      fields    => {
        q => $nif,
      },
    );
  };

  return "" if $@;

  my $cnt = $mech->content();
  return "" unless $cnt;

  $cnt =~ /O NIF $nif pertence . empresa (.*?) Consulte/gms;
  my $name = $1 || "";

  $cnt =~ /NIF: .*? <br\/>(.*?)<br\/>/gms;
  my $postal_code = $1 || "";
  my $city = "";

  if ($name) {
    $name = trim($name);
    $name =~ s/\s+/ /g;
  }

  if ($postal_code) {
    $postal_code = trim($postal_code);
    $postal_code =~ s/\s+/ /g;

    my @a = split / /, $postal_code;

    if (scalar @a) {
      $postal_code = $a[0];
      shift @a;
      $city = join(" ", @a);
    }
  }

  $name = decode_entities($name) if $name;
  $city = decode_entities($city) if $city;

  if (wantarray) {
    return ( $name, $city, $postal_code );
  } else {
    return [ $name, $city, $postal_code ];
  }
}
