#!/usr/bin/perl -w
#
# Usage:
#	potmerge
#		[--quiet]
#		[--init]
#		[--init-only]
#		[--output=<output-dir>]
#		[--sub-dirs=<sub-directories>]
#		--langs=<locales>
#		--lang-dir=<lang-dir>
#		<main-file>
#
# Description:
#	potmerge merges po files into the pot file for an entire book
#	--lang-dir is the directory of the po files
#	if --langs contains more than one lang, <lang-dir> must contain a %s
#	to substitute it with individual langs
#	--langs is a comma-delimited list of locales, which to merge
#
# Author:
#	Bernd Groh <bgroh@redhat.com>
#
=head
    Copyright (C) 2008 Red Hat, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

=cut

use strict;
use warnings;
use Getopt::Long;

my $home = $ENV{'HOME'};
my $startdir = `pwd`;
$startdir =~ s/\/?\n$/\//;

my $langdir = undef;
my $locales = undef;
my $output = './';
my $quiet = 0;
my $subdirs = undef;
my $initial = 0;
my $initial_only = 0;
my $po_append = 0;

GetOptions(
	'i|init|initial' => \$initial,
	'init-only|initial-only' => \$initial_only,
	'q|quiet' => \$quiet,
	'o|output=s' => \$output,
	'd|lang-dir=s' => \$langdir,
	'l|lang|langs=s' => \$locales,
	's|sub|subs|sub-dir|sub-dirs|sub-directory|sub-directories=s' => \$subdirs,
	'p|po-append' => \$po_append
);

if ((!@ARGV) || (!$locales) || (!$langdir)) {
	print STDERR "Usage: potmerge\n\t[--quiet]\n\t[--init] [--init-only]\n\t[--output=<output-dir>]\n\t--langs=<locales>\n\t--lang-dir=<lang-dir>\n\t[--sub-dirs=<sub-directories>]\n\t<main-file>\n";
	exit 0;
}

my $main_file = shift(@ARGV);

if (!(-f $main_file)) {
	print STDERR "$main_file: No such file exists\n";
	exit 0;
}

my $dir = undef;
my $main = undef;

if ($main_file =~ /^(.+\/)([^\/]+\.pot)$/) {
	$dir = $1;
	$main = $2;
} elsif ($main_file =~ /^([^\/]+\.pot)$/) {
	$dir = './';
	$main = $1;
} else {
	print STDERR "$main_file: Not a valid file\n";
	exit 0;
}

if ($langdir =~ /^~\//) {
	$langdir =~ s/^~/$home/;
} elsif ($langdir =~ /^[^\/]/) {
	$langdir = $startdir . $langdir;
}
if (!($langdir =~ /\/$/)) {
	$langdir .= '/';
}

if ($output =~ /^~\//) {
	$output =~ s/^~/$home/;
}
if (!(-d $output)) {
	print STDERR "$output: No such directory exists\n";
	exit 0;
} elsif (!($output =~ /\/$/)) {
	$output .= '/';
}

if ($output ne './') {
	chdir $output or die $0;
}

my @subs = ();
if ($subdirs) {
	@subs = split(',', $subdirs);
}

my @langs = split(',', $locales);
my @lang_dirs = ();

if (@langs > 1) {
	if (!($langdir =~ /%s/)) {
		print STDERR "$langdir: Not a valid lang-dir string\nNeeds to contain a \%s to allow for substitution of langs\n";
		exit 0;
	}
	
	for (my $i = 0; $i < @langs; $i++) {
		my $lang_dir = sprintf($langdir, $langs[$i]);
		
		if (!(-d $lang_dir)) {
			print STDERR "$lang_dir: No such directory exists\n";
			exit 0;
		}
		
		push @lang_dirs, $lang_dir;
		
		if (!(-d $langs[$i])) {
			mkdir $langs[$i] or die $0;
		}
		if ($po_append) {
			if (!(-d ($langs[$i] . '/po'))) {
				mkdir ($langs[$i] . '/po') or die $0;
			}
		}
		
		foreach my $sub (@subs) {
			if (!(-d ($langs[$i] . '/' . $sub))) {
				mkdir ($langs[$i] . '/' . $sub) or die $0;
			}
			if ($po_append) {
				if (!(-d ($langs[$i] . '/' . $sub . '/po'))) {
					mkdir ($langs[$i] . '/' . $sub . '/po') or die $0;
				}
			}
		}
	}
} elsif (@langs == 1) {
	if ($langdir =~ /%s/) {
		$langdir = sprintf($langdir, $langs[0]);
	}
	
	if (!(-d $langdir)) {
		print STDERR "$langdir: No such directory exists\n";
		exit 0;
	}
	
	my $lang = $langs[0];
	
	if (!($langdir =~ /\W$lang\W/)) {
		print STDERR "$langdir: Not a valid lang-dir for the given lang\n";
		exit 0;
	}
	
	push @lang_dirs, $langdir;
	
	if (!(-d $lang)) {
		mkdir $lang or die $0;
	}
	if ($po_append) {
		if (!(-d ($lang . '/po'))) {
			mkdir ($lang . '/po') or die $0;
		}
	}
	
	foreach my $sub (@subs) {
		if (!(-d ($lang . '/' . $sub))) {
			mkdir ($lang . '/' . $sub) or die $0;
		}
		if ($po_append) {
			if (!(-d ($lang . '/' . $sub . '/po'))) {
				mkdir ($lang . '/' . $sub . '/po') or die $0;
			}
		}
	}
}

my $file = undef;
opendir(DIR, $dir) or die "Error: Cannot opendir $dir";
while (defined($file = readdir(DIR))) {
	if ($file =~ /\.pot$/) {
		if (!$quiet) {
			print "Processing $dir$file...\n";
		}
		my $i = 0;
		foreach my $lang (@langs) {
			my $pofile = $lang_dirs[$i] . $file;
			$pofile =~ s/\.pot$/\.po/;
			my $target = "$lang/";
			if ($po_append) {
				$target .= "po/";
			}
			$target .= $file;
			$target =~ s/\.pot$/\.po/;
			if (!(-f $pofile)) {
				foreach my $sub (@subs) {
					$pofile = $lang_dirs[$i] . $sub . '/' . $file;
					$pofile =~ s/\.pot$/\.po/;
					$target = "$lang/$sub/";
					if ($po_append) {
						$target .= "po/";
					}
					$target .= $file;
					$target =~ s/\.pot$/\.po/;
					if (-f $pofile) {
						last;
					}
				}
				if (!(-f $pofile)) {
					foreach my $sub (@subs) {
						my $lang_dir = $lang_dirs[$i];
						$lang_dir =~ s/[^\/]+\/$//;
						$pofile = $lang_dir . $sub . '/' . $file;
						$pofile =~ s/\.pot$/\.po/;
						$target = "$lang/$sub/";
						if ($po_append) {
							$target .= "po/";
						}
						$target .= $file;
						$target =~ s/\.pot$/\.po/;
						if (-f $pofile) {
							last;
						}
					}
				}
			}
			if (-f $pofile) {
				my $msgxmerge = 'msgxmerge -q';
				if (!$quiet) { $msgxmerge .= ' -s'; }
				my $msgmerge = 'msgmerge';
				if ($quiet) { $msgmerge .= ' -q'; }
				if ($initial_only) {
					if (!$quiet) { system("echo initializing $pofile..."); }
					system("$msgxmerge $pofile $dir$file -o $target.init");
					system("msguniq $target.init -o $target");
					system("rm -f $target.init");
					if (!$quiet) { system("echo done."); }
				} elsif ($initial) {
					if (!$quiet) { system("echo initializing $pofile..."); }
					system("$msgxmerge $pofile $dir$file > $target.init");
					system("msguniq $target.init > $target.uniq");
					if (!$quiet) { system("echo done."); }
					if (!$quiet) { system("echo -n merging $pofile..."); }
					system("$msgmerge $target.uniq $dir$file -o $target");
					system("rm -f $target.init $target.uniq");
				} else {
					if (!$quiet) { system("echo -n merging $pofile..."); }
					system("$msgmerge -U $pofile $dir$file");
				}
				if (!$quiet) {
					system("msgfmt -v --output-file=$target.mo $target");
					system("rm -f $target.mo");
				}
			} else {
				$pofile = $lang_dirs[$i] . $file;
				$pofile =~ s/\.pot$/\.po/;
# jfearn: If the po is missing copy the pot to the po
				print STDERR "$pofile: No such file, running msginit\n";
#				`cp $dir$file $pofile`;
				`msginit -i $dir$file -o $pofile -l $lang_dirs[$i] --no-translator`;
			}
			$i++;
		}
		if (!$quiet) {
			print "Done.\n";
		}
	}
}
closedir(DIR);

foreach my $sub (@subs) {
	opendir(DIR, "$dir$sub") or die "Error: Cannot opendir $dir$sub/";
	while (defined($file = readdir(DIR))) {
		if ($file =~ /\.pot$/) {
			if (!$quiet) {
				print "Processing $dir$sub/$file...\n";
			}
			my $i = 0;
			foreach my $lang (@langs) {
				my $pofile = $lang_dirs[$i] . $sub . '/' . $file;
				$pofile =~ s/\.pot$/\.po/;
				my $target = "$lang/$sub/";
				if ($po_append) {
					$target .= "po/";
				}
				$target .= $file;
				$target =~ s/\.pot$/\.po/;
				if (!(-f $pofile)) {
					my $lang_dir = $lang_dirs[$i];
					$lang_dir =~ s/[^\/]+\/$//;
					$pofile = $lang_dir . $sub . '/' . $file;
					$pofile =~ s/\.pot$/\.po/;
				}
				if (-f $pofile) {
					my $msgxmerge = 'msgxmerge -q';
					if (!$quiet) { $msgxmerge .= ' -s'; }
					my $msgmerge = 'msgmerge';
					if ($quiet) { $msgmerge .= ' -q'; }
					if ($initial_only) {
						if (!$quiet) { system("echo initializing $pofile..."); }
						system("$msgxmerge $pofile $dir$sub/$file > $target.init");
						system("msguniq $target.init > $target");
						system("rm -f $target.init");
						if (!$quiet) { system("echo done."); }
					} elsif ($initial) {
						if (!$quiet) { system("echo initializing $pofile..."); }
						system("$msgxmerge $pofile $dir$sub/$file > $target.init");
						system("msguniq $target.init > $target.uniq");
						if (!$quiet) { system("echo done."); }
						if (!$quiet) { system("echo -n merging $pofile..."); }
						system("$msgmerge $target.uniq $dir$sub/$file > $target");
						system("rm -f $target.init $target.uniq");
					} else {
						if (!$quiet) { system("echo -n merging $pofile..."); }
						system("$msgmerge $pofile $dir$sub/$file > $target");
					}
					if (!$quiet) {
						system("msgfmt -v --output-file=$target.mo $target");
						system("rm -f $target.mo");
					}
				} else {
					my $pofile = $lang_dirs[$i] . $sub . '/' . $file;
					my $lang_dir = $lang_dirs[$i].$sub;

					$pofile =~ s/\.pot$/\.po/;
					my $cmd = "msginit -i $dir$sub/$file -o $pofile -l $lang_dir --no-translator";
					print STDERR "$pofile: No such file, running msginit\n\t($cmd)\n";
					`$cmd`;
				}
				$i++;
			}
			if (!$quiet) {
				print "Done.\n";
			}
		}
	}
	closedir(DIR);
}
