#!/usr/bin/perl -w

use utf8;
use warnings;
use strict;

BEGIN {
    unshift @INC, ( $ENV{POPHOME} || '@POPHOME@' ) . '/lib'
      unless $ENV{KUNDE_NO_PERLPATH};
}

use Cf qw($KONFIG_SUCHLISTE);
use Dbase::Getopt;
use Dbase::Help qw(Do DoFn DoTrans qquote);

use constant KEEP_LOCAL => {
    map +( $_ => undef ), qw(
      DATABASE
      DATAHOST
      DATAHOST2
      DATAPASS
      DATAUSER
      DBCACHE_TIMEOUT
      DBCMD_TIMEOUT
      DBDATABASE
      GROUP
      KONFIG_SUCHLISTE
      MODE
      OWNER
      REAL_MAILDOM
      )
};

GetOptions( 'verbose+' => \my $Verbose );

my ($namensraum) = split ' ', $KONFIG_SUCHLISTE, 2;
my $id_namensraum =
  DoFn( 'SELECT id FROM konfig_namensraum WHERE name = ' . qquote($namensraum) )
  or die "Unbekannter Namensraum: $namensraum\n";

my $popconf = $ENV{POPCONFIG};
$popconf = '@POPCONFIG@' unless defined $popconf;

open my $fh, '<', $popconf or die qq(Kann "$popconf" nicht oeffnen: $!\n);

DoTrans {
    my $comments;

    while (<$fh>) {
        s/\s*(#.*)// and $comments .= "$1\n";
        next if /^\s*$/;

        my ( $name, $wert ) = /^([^=]+)=(.*)$/
          or die "$popconf: Zeile $.: '$_' verstehe ich nicht.\n";

        if ( exists KEEP_LOCAL->{$name} || $name =~ /^START_/ ) {
            print defined $comments && "\n$comments", $_;
        }
        elsif (
            !defined(
                my $id_variable = DoFn(
                    'SELECT id FROM konfig_variable WHERE name = '
                      . qquote($name)
                )
            )
          )
        {
            warn "Unbekannte Konfigurationsvariable: $_";
        }
        else {
            $wert =~ s/^(["'])(.*)\1\s*$/$2/;

            my ( $db_wert, $nr );
            for ( split ' ', $KONFIG_SUCHLISTE ) {
                if ( defined( $db_wert = DoFn(<<_) ) ) {
	SELECT W.wert
	FROM   konfig_wert W
	JOIN   konfig_namensraum N ON N.id = W.namensraum
	JOIN   konfig_variable   V ON V.id = W.variable
	WHERE  N.name = ${\ qquote($_) } AND V.name = ${\ qquote($name) }
_
                    $nr = $_;
                    last;
                }
            }
            if ( defined $db_wert && $db_wert eq $wert ) {
                print STDERR "Bereits in Datenbank (Namensraum $nr): $_"
                  if $Verbose;
            }
            elsif (defined $db_wert
                && $db_wert ne $wert
                && $nr eq $namensraum )
            {
                print STDERR
                  qq(Abweichender Wert "$db_wert" im Namensraum $nr: $_\n)
                  if $Verbose;
                print defined $comments && "\n$comments", $_;
            }
            else {
                Do(<<_);
	INSERT INTO konfig_wert
	SET namensraum = $id_namensraum,
	    variable   = $id_variable,
	    wert       = ${\ qquote($wert) }
_
                print STDERR
                  "In Datenbank eingefügt (Namensraum $namensraum): $_"
                  if $Verbose;
            }
        }

        undef $comments;
    }
}

__END__

=head1 NAME

konfig2db - lokale @POPCONFIG@ in die Datenbank übertragen

=head1 SYNOPSE

    konfig2db >tempfile && mv tempfile @POPCONFIG@

=head1 BESCHREIBUNG

Das Programm liest die lokale @POPCONFIG@ (oder bevorzugt die in der
Umgebungsvariable POPCONFIG angegebene Datei) und vergleicht deren Inhalt mit
der in der Datenbank vorhandenen Konfiguration.

Soweit es sich um Variablen handelt, die lokal definiert sein müssen oder um
Fälle, bei denen in der Datenbank im primären Namensraum (= dem in der
C<$KONFIG_SUCHLISTE> erstgenannten) bereits ein abweichender Wert gespeichert
ist, werden die Einstellungen sowie zugehörige Kommentare auf der
Standardausgabe wieder ausgegeben.

Andernfalls wird der Wert im primären Namensraum in der Datenbank gespeichert,
soweit er dort noch nicht vorhanden war.

=head1 OPTIONEN

=over 4

=item -verbose

um auf der Standardfehlerausgabe zusätzliche Informationen darüber zu erhalten,
was das Programm tut.

=item -help

=item -?

um (nur) diese Dokumentation anzeigen zu lassen

=back

