#!/usr/bin/perl -w

use strict;
use warnings;
use DBI;
use File::Basename;

my $dbh;
my $sth_insert_files;
my $sth_insert_category;
my $sth_insert_mimetype;
my $sth_max;

my $pkgkey=$ENV{'REPOCOP_PKG_KEY'};

exit if $ENV{'REPOCOP_PKG_NAME'} =~ m/^repocop-demo-menu/;

my @findpath;
foreach (qw!
/usr/share/applnk
/usr/share/apps
/usr/share/applications
/usr/share/servicetypes
/usr/share/services
/usr/share/kde/applications
/usr/share/kde/servicetypes
/usr/share/kde/services
/usr/share/kde4/applications
/usr/share/kde4/servicetypes
/usr/share/kde4/services
/usr/share/kf5/applications
/usr/share/kf5/servicetypes
/usr/share/kf5/services
/usr/lib64/LibreOffice4/share/xdg
/usr/lib64/LibreOffice/share/xdg
!) {
    push @findpath,$ENV{'REPOCOP_PKG_ROOT'}.$_ if -d $ENV{'REPOCOP_PKG_ROOT'}.$_;
}
exit 0 unless @findpath;

&connect();

# global hash, to make bool2i calls simple
my %key;
# boolean key to {0,1}
sub bool2i {
    my ($arg)=@_;
    my $val=$key{$arg};
    return 0 if (not $val);
    return 0 if $val eq 'false' or $val eq '0';
    return 1;
}

open my $dh, "find @findpath -name '*.desktop' |"  or die $!;
#foreach my $filename(glob $ENV{'REPOCOP_PKG_ROOT'}."/usr/share/applications/*.desktop") {
while (my $filename=<$dh>) {
    chomp $filename;
    if ((not -e $filename) and -l $filename) {
	my $tryname=$ENV{'REPOCOP_PKG_ROOT'}.readlink($filename);
	if (-e $tryname) {
	    $filename=$tryname;
	} else {
	    warn "Oops: deep or missing symlink $tryname";
	}
    }
    open my $fh, $filename or die "freedesktop_desktop.test: $filename: $!";
    %key=();
    my $rawfile='';
    while (<$fh>) {
	$rawfile.=$_;
	chomp;
	s/\s+$//;
	$key{$1}=$2 if /^(\w+)=(.*)/;
    }
    close $fh;
    $filename=~s/^$ENV{'REPOCOP_PKG_ROOT'}//;
    if ($filename=~m!^/usr/share(?:|/kde4|/kde|/kf5)/applications/!) {
	if ($key{'Type'} eq 'X-Thumbnailer') {
	    system('repocop-test-warn', "X-Thumbnailer file $filename should be installed to /usr/share/thumbnailers, not to /usr/share/applications.");
	} else {
	    my $retval=`desktop-file-validate $ENV{'REPOCOP_PKG_ROOT'}$filename`;
	    chomp $retval;
	    if ($retval) {
		$retval=~s/$ENV{'REPOCOP_PKG_ROOT'}//g;
		if ($retval=~/error:/) {
		    system('repocop-test-warn', "desktop-file-validate utility exited abnormally with the following message(s):",$retval);
		} else {
		    system('repocop-test-info', "desktop-file-validate utility printed the following message(s):",$retval);
		}
	    }
	}
    }
    $sth_max->execute();
    my ($desktopid)=$sth_max->fetchrow_array();
    $desktopid||=0;
#       DESKTOPTYPE TEXT DEFAULT '',
#       ICON TEXT DEFAULT '',
#       APPEXEC TEXT DEFAULT '',
#       IS_HIDDEN INTEGER,
#       IS_ONLYSHOWIN INTEGER,
#       IS_NOTSHOWIN INTEGER,
#       IS_NODISPLAY INTEGER,
#       IS_TERMINAL INTEGER,

    my $fddir=dirname($filename);
    my $fdname=basename($filename);
    # hack around LibreOffice
    if ($fddir eq '/usr/lib64/LibreOffice/share/xdg') {
	$fddir='/usr/share/applications';
	#my $oversion='5.1';
	#my $rver=$ENV{'REPOCOP_PKG_VERSION'};
	#$oversion=substr($rver,0,3) if $rver;
	#$fdname='libreoffice'.$oversion.'-'.$fdname;
    }

    $sth_insert_files->execute($desktopid,$pkgkey,$fddir,$fdname,
			       $key{'Type'},$key{'Icon'},$key{'Exec'},$rawfile,
			       bool2i('Hidden'),bool2i('OnlyShowIn'),bool2i('NotShowIn'),bool2i('NoDisplay'),
			       bool2i('Terminal'));
    if ($key{'Categories'}) {
	foreach (split (';',$key{'Categories'})) {
	    $sth_insert_category->execute($desktopid,$_) if $_;
	}
    }

    if ($key{'MimeType'}) {
	foreach (split (';',$key{'MimeType'})) {
	    $sth_insert_mimetype->execute($desktopid,$_) if $_;
	}
    }
}

&disconnect();

sub connect {
    my $dbfile=$ENV{'REPOCOP_TEST_DB'};
    die "database is not initialized properly!" unless $dbfile;
    $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","","", {
	PrintError => 1,
	AutoCommit => 0,
			}) or die $dbh->errstr;
    $sth_max=$dbh->prepare('SELECT MAX(DESKTOPID)+1 FROM freedesktop_desktop');
    $sth_insert_files=$dbh->prepare('INSERT INTO freedesktop_desktop VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)') or die $dbh->errstr;
    $sth_insert_category=$dbh->prepare('INSERT INTO freedesktop_desktop_categories VALUES(?,?)') or die $dbh->errstr;
    $sth_insert_mimetype=$dbh->prepare('INSERT INTO freedesktop_desktop_mimetypes VALUES(?,?)') or die $dbh->errstr;
}

sub disconnect {
    $dbh->commit;
    $sth_max->finish;
    $sth_insert_files->finish;
    $sth_insert_category->finish;
    $sth_insert_mimetype->finish;
    # no need now?
    # hack around closing dbh with active statement handles bug
    #local $SIG{'__WARN__'} = sub {};
    $dbh->disconnect;
}

