#!/usr/bin/perl
# Based on Build.PL from po4a

use Module::Build;
use strict;
use warnings;

my $builder = Module::Build->subclass
    (
     class => 'My::Builder',
     code => q{
	 { use strict;
	 my $bin_po_dir = 'po';
	 my $bin_pot_file = 'bin.pot';
	 my $bin_po_prefix = 'bin.';
	 my $bin_pot_path = "$bin_po_dir/$bin_pot_file";
	 my $doc_po_dir = 'po';
	 my $doc_pot_file = 'doc.pot';
	 my $doc_po_prefix = 'doc.';
	 my $doc_pot_path = "$doc_po_dir/$doc_pot_file";
	 my $base_dir = '..';
	 my $bin_mo_file = 'Parse-DebianChangelog';
	 my $doc_mo_file = 'Parse-DebianChangelog-Pod';
	 my $po4a_path = '';

	 sub ACTION_build {
	     my $self = shift;
	     $self->depends_on('code');
	     $self->depends_on('docs');
	     $self->depends_on('distmeta'); # regenerate META.yml
	     $self->depends_on('man');
	     $self->depends_on('postats');
	 }
	 sub ACTION_install {
	     my $self = shift;

	     require ExtUtils::Install;
#	    $self->depends_on('build');

	     ExtUtils::Install::install($self->install_map, 1, 0,
					$self->{args}{uninst}||0);
	 }
	 sub ACTION_binpo {
	     my $self = shift;

	     my @files = sort( (keys(%{$self->script_files()}),
				@{$self->rscan_dir('lib',qr/\.pm$/)}));

	     unless ($self->up_to_date(\@files, $bin_pot_path)) {
		 print "XX Update $bin_pot_path\n";
		 my $podfiles = join ("", map { " $base_dir/$_" } @files);
		 system("cd $bin_po_dir; xgettext --copyright-holder=\"Frank Lichtenheld\" --keyword=__g --msgid-bugs-address=frank\@lichtenheld.de -L Perl $podfiles -o $bin_pot_file.new") && die;
		 if ( -e $bin_pot_path) {
		     my $diff = qx(diff -q -I'#:' -I'POT-Creation-Date:' -I'PO-Revision-Date:' $bin_pot_path $bin_pot_path.new);
		     if ( $diff eq "" ) {
			 unlink "$bin_pot_path.new" || die;
			 # touch it
			 my ($atime, $mtime) = (time,time);
			 utime $atime, $mtime, $bin_pot_path;
		     } else {
			 rename "$bin_pot_path.new", $bin_pot_path || die;
		     }
		 } else {
		     rename "$bin_pot_path.new", $bin_pot_path || die;
		 }
	     } else {
		 print "XX $bin_pot_path uptodate.\n";
	     }

	     # update languages
	     @files = @{$self->rscan_dir($bin_po_dir,qr/\/\Q$bin_po_prefix\E.*\.po$/)};
	     foreach (@files) {
		 next if m|/.#|;
		 $_ =~ /.*\/(?:.*\.)?(.*)\.po$/;
		 my $lang = $1;

		 unless ($self->up_to_date($bin_pot_path,
					   "$bin_po_dir/$bin_po_prefix$lang.po")) {
		     print "XX Sync $bin_po_dir/$bin_po_prefix$lang.po: ";
		     system('msgmerge', "$bin_po_dir/$bin_po_prefix$lang.po",
			    "$bin_pot_path",
			    "-o", "$bin_po_dir/$bin_po_prefix$lang.po.new")
			 && die;
		     # Typically all that changes was a date. I'd
		     # prefer not to cvs commit such changes, so
		     # detect and ignore them.
		     my $diff = qx(diff -q -I'#:' -I'POT-Creation-Date:' -I'PO-Revision-Date:' $bin_po_dir/$bin_po_prefix$lang.po $bin_po_dir/$bin_po_prefix$lang.po.new);
		     if ($diff eq "") {
			 unlink "$bin_po_dir/$bin_po_prefix$lang.po.new" || die;
			 # touch it
			 my ($atime, $mtime) = (time,time);
			 utime $atime, $mtime,
			       "$bin_po_dir/$bin_po_prefix$lang.po";
		     } else {
			 rename "$bin_po_dir/$bin_po_prefix$lang.po.new",
			       "$bin_po_dir/$bin_po_prefix$lang.po" || die;
		    }
		 } else {
		     print "XX $bin_po_dir/$bin_po_prefix$lang.po uptodate.\n";
		 }
		 unless ($self->up_to_date("$bin_po_dir/$bin_po_prefix$lang.po",
					   "blib/po/$lang/LC_MESSAGES/$bin_mo_file.mo")) {
		     print "X Generate $bin_mo_file.mo for $lang.\n";
		     system('mkdir', '-p', "blib/po/$lang/LC_MESSAGES") && die;
		     system('msgfmt', '-o',
			    "blib/po/$lang/LC_MESSAGES/$bin_mo_file.mo",
			    "$bin_po_dir/$bin_po_prefix$lang.po") && die;
		 } else {
		     print "XX $bin_mo_file.mo for $lang uptodate.\n";
		 }
	     }

	 }
	 sub ACTION_manpo {
	     my $self = shift;

	     # update pot
	     my @files = sort( (keys(%{$self->script_files()}),
				@{$self->rscan_dir('lib',qr/\.pm$/)}));
	     unless ($self->up_to_date(\@files, $doc_pot_path)) {
		 my $podfiles = join ("", map {" -m $base_dir/$_" } @files);
		 print "XX Update documentation pot files: ";
		 system("cd $doc_po_dir; ${po4a_path}po4a-updatepo -f pod $podfiles -M utf-8 -p $doc_pot_file")
		     && die;
		 my ($atime, $mtime) = (time,time);
		 utime $atime, $mtime, $doc_pot_path;

	     } else {
		 print "XX Documentation pot file uptodate.\n";
	     }

	     # update languages
	     @files = @{$self->rscan_dir($doc_po_dir,qr/\.po$/)};
	     foreach (@files) {
		 $_ =~ /.*\/(?:.*\.)?(.*)\.po$/;
		 my $lang = $1;

		 unless ($self->up_to_date($doc_pot_path,
					   "$doc_po_dir/$doc_po_prefix$lang.po")) {
		     print "XX Update documentation $doc_po_prefix$lang.po: ";

		     system('msgmerge', "$doc_po_dir/$doc_po_prefix$lang.po",
			    "$doc_pot_path",
			    '-o', "$doc_po_dir/$doc_po_prefix$lang.po.new")
			 && die;

		     # Typically all that changes was a date. I'd
		     # prefer not to cvs commit such changes, so
		     # detect and ignore them.
		     my $diff = qx(diff -q -I'#:' -I'POT-Creation-Date:' -I'PO-Revision-Date:' $doc_po_dir/$doc_po_prefix$lang.po $doc_po_dir/$doc_po_prefix$lang.po.new);
		     if ( $diff eq "" ) {
			 unlink "$doc_po_dir/$doc_po_prefix$lang.po.new" || die;
			 my ($atime, $mtime) = (time,time);
			 utime $atime, $mtime,
			       "$doc_po_dir/$doc_po_prefix$lang.po";
		     } else {
			 rename "$doc_po_dir/$doc_po_prefix$lang.po.new",
			       "$doc_po_dir/$doc_po_prefix$lang.po" || die;
		     }
		 } else {
		     print "XX Documentation $doc_po_prefix$lang.po uptodate.\n";
		 }
		 unless ($self->up_to_date("$doc_po_dir/$doc_po_prefix$lang.po",
					   "blib/po/$lang/LC_MESSAGES/$doc_mo_file.mo")) {
		     print "X Generate $doc_mo_file.mo for $lang.\n";
		     system('mkdir', '-p', "blib/po/$lang/LC_MESSAGES") && die;
		     system('msgfmt', '-o',
			    "blib/po/$lang/LC_MESSAGES/$doc_mo_file.mo",
			    "$doc_po_dir/$doc_po_prefix$lang.po") && die;
		 } else {
		     print "XX $doc_mo_file.mo for $lang uptodate.\n";
		 }
	     }
	 }
	 sub ACTION_man {
	     my $self = shift;

	     $self->depends_on('manpo');
	     use Pod::Man;

	     my $options = "-v -f pod -M utf-8 -L iso8859-1";

	     #get the languages
	     my @langs = @{$self->rscan_dir($doc_po_dir,qr/\.po$/)};
	     my $i=0;
	     while ($i < @langs) {
		 $langs[$i] =~ /.*\/(?:.*\.)?(.*)\.po$/;
		 $langs[$i] = $1;
		 $i++;
	     }

	     system("rm", "-rf", "blib/man") && die;
	     system("mkdir", "-p", "blib/man") && die;

	     # Translate binaries manpages
	     my $parser = Pod::Man->new (release => "parsechangelog",
					 center => "parsechangelog",
					 section => "1p");

	     foreach my $lang (@langs) {
		 print ("X Translate binary manpages to $lang\n");
		 foreach my $file (keys(%{$self->script_files()})) {
		     system("${po4a_path}po4a-translate $options -m $file -p $doc_po_dir/$doc_po_prefix$lang.po -l blib/man/$file")
			 && die;
		     if (-e "blib/man/$file") {
			 system("mkdir", "-p", "blib/man/$lang/man1") && die;
			 $parser->parse_from_file ("blib/man/$file",
						   "blib/man/$lang/man1/$file.1p");
			 system("gzip", "-9f", "blib/man/$lang/man1/$file.1p")
			     && die;
			 system("rm", "-f", "blib/man/$file")
			     && die;
		     }
		 }
	     }

	     # Translate modules manpages
	     $parser = Pod::Man->new (release => "Parse::DebianChangelog",
				      center => "Parse::DebianChangelog",
				      section => "3pm");

	     foreach my $lang (@langs) {
		 print ("X Translate module manpages to $lang\n");
		 foreach my $file (@{$self->rscan_dir('lib',qr/\.pm$/)}) {
		     $file =~ /.*\/(.*)\.pm$/;
		     my $filename = $1;
		     system("${po4a_path}po4a-translate $options -m $file -p $doc_po_dir/$doc_po_prefix$lang.po -l blib/man/$filename")
			 && die;
		     if (-e "blib/man/$filename") {
			 system ("mkdir", "-p", "blib/man/$lang/man3") && die;
			 $parser->parse_from_file ("blib/man/$filename",
						   "blib/man/$lang/man3/Parse::DebianChangelog::$filename.3pm")
			     || die;
			 system ("gzip", "-9f",
				 "blib/man/$lang/man3/Parse::DebianChangelog::$filename.3pm")
			     && die "Cannot gzip blib/man/$lang/man3/Parse::DebianChangelog::$filename.3pm";
			 system ("rm", "-f", "blib/man/$filename") && die;
		     }
		 }
	     }

	 }
	 sub ACTION_dist {
	     my ($self) = @_;

	     $self->depends_on('test');
	     $self->depends_on('distdir');

	     my $dist_dir = $self->dist_dir;

	     if ( -e "$dist_dir.tar.gz") {
		 # Delete the distfile if it already exists
		 system ("rm", "$dist_dir.tar.gz") && die;
	     }

	     $self->make_tarball($dist_dir);
	     $self->delete_filetree($dist_dir);
	 }
	 sub ACTION_postats {
	     my $self = shift;
	     $self->depends_on('binpo');
	     $self->depends_on('manpo');
	     $self->postats($bin_po_dir);
	     $self->postats($doc_po_dir) unless $bin_po_dir eq $doc_po_dir;
	 }
	 sub postats {
	     my ($self,$dir) = (shift,shift);
	     my $potsize = `(cd $dir;ls -sh *.pot) | sed -n -e 's/^ *\\\\([^[:blank:]]*\\\\).*\$/\\\\1/p'`;
	     $potsize =~ /(.*)/;
	     print "$dir (pot: $1)\n";
	     my @files = @{$self->rscan_dir($dir,qr/\.po$/)};
	     foreach (@files) {
		 my $file = $_;
		 $file =~ /.*\/(?:.*\.)?(.*)\.po$/;
		 my $lang = $1;
		 my $stat = `msgfmt -o /dev/null -c -v --statistics $file 2>&1`;
		 print "  $lang: $stat";
	     }
	 } }
     },
     );

my $base= $Config::Config{man1dir};
$base =~ s/\/man\/man1//;

my $b = $builder->new
    ( module_name => 'Parse-DebianChangelog',
      license => 'gpl',
      dist_version_from => 'lib/Parse/DebianChangelog.pm', # finds $VERSION
      requires => { 'Date::Parse' => 0,
		    'Locale::gettext' => 0 },
      recommends => { 'IO::String' => 0, 'HTML::Parser' => 0,
		      'HTML::Entities' => 0, 'HTML::Template' => 0,
		      'XML::Simple' => 0 },
      build_requires => { 'Test::Pod' => 0, 'Test::Pod::Coverage' => 0 },
      script_files => [ 'bin/parsechangelog' ],
      add_to_cleanup => [ 'messages.mo', 'blib', '$doc_pot_path~' ],
      install_path => {po => $base.'/locale', man => $base.'/man'},
      create_packlist => 0,
      dist_abstract => 'parse Debian changelogs and output them in other formats',
      dist_author => ['Frank Lichtenheld <djpig@debian.org>']
      )->create_build_script;
