# po-debconf -- lintian check script -*- perl -*-

# Copyright (C) 2002-2004 by Denis Barbier <barbier@linuxfr.org>
#
# 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, you can find it on the World Wide
# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301, USA.

package Lintian::po_debconf;
use strict;
use warnings;

use Lintian::Tags qw(tag);
use Lintian::Util qw(fail system_env);

sub run {

my $pkg = shift;
my $type = shift;
my $info = shift;

my $full_translation = 0;
my $debfiles = $info->debfiles;

# First, check wether this package seems to use debconf but not po-debconf.
# Read the templates file and look at the template names it provides, since
# some shared templates aren't translated.
opendir(DEB, $debfiles)
    or fail("Can't open debfiles directory.");
my $has_template = my $has_depends = my $has_config = 0;
my @lang_templates;
for my $file (readdir(DEB)) {
    next if -d "$debfiles/$file";
    if ($file =~ m/^(.+\.)?templates(\..+)?$/) {
        if ($file =~ m/templates\.\w\w(_\w\w)?$/) {
            push (@lang_templates, $file);
        } else {
            open(PO, '<', "$debfiles/$file")
                or fail("Can't open debfiles/$file file.");
            my $in_template = 0;
            while (<PO>) {
                tag 'translated-default-field', "$file: $."
                    if (m/^_Default(Choice)?: [^\[]*$/);
                if (/^Template: (\S+)/i) {
                    my $template = $1;
                    next if $template =~ m,^shared/packages-(wordlist|ispell)$,;
                    next if $template =~ m,/languages$,;
                    $in_template = 1;
                } elsif ($in_template and /^_?Description: (.+)/i) {
                    my $description = $1;
                    next if $description =~ /for internal use/;
                    $has_template = 1;
                } elsif ($in_template and /^$/) {
                    $in_template = 0;
                }
            }
            close PO;
        }
    }
}
closedir(DEB);

#TODO: check whether all templates are named in TEMPLATES.pot
if ( $has_template ) {
    if ( ! -d "$debfiles/po" ) {
        tag 'not-using-po-debconf';
        return 0;
    }
} else {
    return 0;
}

# If we got here, we're using po-debconf, so there shouldn't be any stray
# language templates left over from debconf-mergetemplate.
for (@lang_templates) {
    tag 'stray-translated-debconf-templates', $_ unless /templates\.in$/;
}

my $missing_files = 0;

if ( -f "$debfiles/po/POTFILES.in") {
    open(POTFILES, '<', "$debfiles/po/POTFILES.in")
        or fail("Can't open debfiles/po/POTFILES.in.");
    while (<POTFILES>) {
        chomp;
        next if /^\s*\#/;
        s/.*\]\s*//;
        #  Cannot check files which are not under debian/
        next if m,^\.\./, or $_ eq '';
        unless (-f "$debfiles/$_") {
            tag 'missing-file-from-potfiles-in', $_;
            $missing_files = 1;
        }
    }
    close(POTFILES);
} else {
    tag 'missing-potfiles-in';
    $missing_files = 1;
}
if (! -f "$debfiles/po/templates.pot") {
    tag 'missing-templates-pot';
    $missing_files = 1;
}

if (-x '/usr/bin/msgcmp' && -x '/usr/share/intltool-debian/intltool-update' ) {
    if ($missing_files == 0) {
        $ENV{'INTLTOOL_EXTRACT'} ||= '/usr/share/intltool-debian/intltool-extract';
        system_env("cd \Q$debfiles/po\E && /usr/share/intltool-debian/intltool-update --gettext-package=test --pot");
        system_env("/usr/bin/msgcmp --use-untranslated \Q$debfiles/po/test.pot\E \Q$debfiles/po/templates.pot\E >/dev/null 2>&1"
                   . "&& /usr/bin/msgcmp --use-untranslated \Q$debfiles/po/templates.pot\E \Q$debfiles/po/test.pot\E >/dev/null 2>&1") == 0
                or tag 'newer-debconf-templates';
    }
} else {
    fail('either msgcmp or intltool-update not found');
}

if (! -x '/usr/bin/msgfmt' ) {
    fail('msgfmt not found');
}
opendir(DEBIAN, "$debfiles/po")
        or fail("Can't open debfiles/po directory.");
while (defined(my $file=readdir(DEBIAN))) {
    next unless $file =~ m/\.po$/;
    tag 'misnamed-po-file', "debian/po/$file"
        unless ($file =~ /^[a-z]{2,3}(_[A-Z]{2})?(?:\@[^\.]+)?\.po$/o);
    local ($/) = "\n\n";
    $_ = '';
    open(PO, '<', "$debfiles/po/$file")
        or fail("Can't open debfiles/po/$file file.");
    while (<PO>) {
        last if m/^msgstr/m;
    }
    close(PO);
    unless ($_) {
        tag 'invalid-po-file', "debian/po/$file";
        next;
    }
    s/"\n"//g;
    my $charset = '';
    if (m/charset=(.*?)\\n/) {
        $charset = ($1 eq 'CHARSET' ? '' : $1);
    }
    tag 'unknown-encoding-in-po-file', "debian/po/$file"
            unless length($charset);
    system_env("msgfmt -o /dev/null \Q$debfiles/po/$file\E 2>/dev/null") == 0
        or tag 'invalid-po-file', "debian/po/$file";

    my $stats = `LC_ALL=C msgfmt -o /dev/null --statistics \Q$debfiles/po/$file\E 2>&1`;
    if (!$full_translation && $stats =~ m/^\w+ \w+ \w+\.$/) {
        $full_translation = 1;
    }
}
closedir DEBIAN;

tag 'no-complete-debconf-translation' if !$full_translation;

}

1;

# Local Variables:
# indent-tabs-mode: nil
# cperl-indent-level: 4
# End:
# vim: syntax=perl sw=4 sts=4 sr et
