#!/usr/bin/perl -w

use lib "/usr/lib/YaST2/agents_non_y2";
use ycp;
use strict;

# current pattern
my %pattern		= ();

# list of all patterns in current file
my @patterns		= ();

# error code
my $err_no		= 0;

# which keys have multiline values
my %multiple		= (
    "Des"	=> 1,
    "Ins"	=> 1,
    "Del"	=> 1,
    "Eul"	=> 1
);

# parse the input file (given as argument) and fill the %pattern hash
sub parse_file {

    my $file	= shift;
    @patterns	= ();
    %pattern	= ();
    my $i = open(PATTERN, $file =~ /\.gz$/ ? "/usr/bin/gunzip -c '$file' |" : "< $file");
    if (!defined $i) {
	y2error ("$file cannot be opened for reading!");
	$err_no		= 1;
        return 0;
    }
    my $multiline_key	= "";
    my $multiline_val	= "";
    foreach my $line (<PATTERN>) {
	chomp $line;
	if ($line =~ /^=([\w\.]+):[ \t]*(.*)/) {
	    if ($1 eq "Ver" && %pattern) {
		y2debug ("new pattern; saving ", $pattern{"Pat"} || "-");
		my %pat		= %pattern;
		push @patterns, \%pat;
		%pattern	= ();
	    }
	    $pattern{$1}	= $2;
	}
	elsif ($line =~ /^\+([\w\.]+):.*/) {
	    $multiline_key	= $1;
	    $multiline_val	= "";
	}
	elsif ($line =~ /^\-([\w\.]+):.*/) {
	    if ($multiline_key eq $1) {
		$pattern{$multiline_key}	= $multiline_val;
	    }
	    else {
		y2error ("ending key is $1, while starting was $multiline_key");
	    }
	}
	elsif ($multiline_key) {
	    $multiline_val	= $multiline_val."\n" if ($multiline_val);
	    $multiline_val      = $multiline_val.$line;
	}
    }
    push @patterns, \%pattern if (%pattern);
    close PATTERN;
    return 1;
}

# write the file; 1st argument is path, 2nd data hash
sub write_file {

    my $file	= shift;
    my $pat	= shift;

    if (ref ($pat) ne "HASH" || !%{$pat}) {
	y2error ("data not hash or empty");
	$err_no	= 10;
	return 0;
    }
    my $o = open(PATTERN, $file =~ /\.gz$/ ? "| /usr/bin/gzip -9 -c '$file'" : "> $file");
    if (!defined $o) {
	y2error ("$file cannot be opened for writing!");
	$err_no	= 11;
        return 0;
    }
    my $cont	= "";
    while (my ($key, $val) = each %{$pat}) {
	next if (!$val);
	if (defined $multiple{$key}) {
	    $cont	= $cont."+$key:\n$val\n-$key:\n";
	}
	else {
	    $cont	= $cont."=$key: $val\n";
	}
    }
    print PATTERN $cont;
    close PATTERN;
    return 1;
}

# --------------------------------------- main -----------------------------
while (<STDIN>)
{

    my ($command, $path, $argument) = ycp::ParseCommand ($_);

    y2debug ("command: $command, path: $path");
    
    if ($command eq "Read")
    {
	y2debug ("argument: $argument");

	# return pattern map from given file(last one if there are more of them)
	if ($path eq '.' && $argument) {
	    if (parse_file ($argument)) {
		ycp::Return (\%pattern);
	    }
	    else {
		ycp::Return ({});
	    }
	}
	# return list of pattern maps from given file
	elsif ($path eq '.list' && $argument) {
	    if (parse_file ($argument)) {
		ycp::Return (\@patterns);
	    }
	    else {
		ycp::Return ([]);
	    }
	}
	else {
	    y2error ("wrong path ($path) or argument: ", ref ($argument));
	    ycp::Return("false");#FIXME nil?
	}
    }
    elsif ($command eq "Write") # FIXME not complete, do not use
    {
	y2debug ("argument: $argument");
	if ($path eq '.' && ref ($argument) eq "ARRAY") {
	    if (write_file ($argument->[0], $argument->[1])) {
		ycp::Return("true");
	    }
	    else {
		ycp::Return("false");
	    }
	}
	else {
	    y2error ("wrong path ($path) or argument: ", ref ($argument));
	    ycp::Return("false");
	}
    }
    elsif ($command eq "result")
    {
	exit;
    }
    else
    {
	y2error ("wrong command: $command");
	ycp::Return("wrong command ($command)");
    }
}

# end
