#!/bin/sh
exec perl -x $0 $@

#!perl

my @configuration=(
   [  'db-host=host',               'localhost',   'hostname of the database server' ],
   [  'db-admin-user=user',         'root',        'username of the database administrator' ],
   [  'db-admin-password=password', '',            'password of the database administrator' ],
   [  'db-user=user',               'midgard',     'username of the midgard database user' ],
   [  'db-user-password=password',  'midgard',     'password of the midgard database user' ],
   [  'db=databasename',            'midgard',     'database name' ],
   [  'host=hostname',              'localhost',   'hostname of this machine' ],
   [  'ip=ipaddress',               '',            'IP address of this machine' ],
   [  'port=portnumber',            '80',          'port number for this server' ],
   [  'blobdir=DIR',                '',            'directory where BLOBs will be stored' ],
   [  'pagecache=DIR',              '',            'directory where mod-preparser will store generated pages' ],
   [  'midgard=DIR',                '',            'installation directory of Midgard' ],
   [  'apxs=PROGRAM',               '',            'full path of the apxs binary' ],
   [  'apache-user=user',           '',            'username that apache runs as' ],
   [  'apache-group=group',         '',            'group that apache runs as' ],
   [  'admin-user',                 'admin',       'name of the default user' ],
   [  'admin-pass',                 'password',    'password of the default user' ],
   [  'adminsite',                  'yes',         'install the 1.2.5 adminsite' ],
   [  'lang=language',              'en',          'the 1.2.5 adminsite language' ],
   [  'asgard',                     'yes',         'install the Asgard admin site' ],
   [  'asgard-ru',                  'no',          'install the russian translation for Asgard' ],
   [  'php=version',                '4',           'defaults for php version 3 or 4' ],
   [  'install=new|upgrade',        '',            'install new database or upgrade existing' ]
);

use Getopt::Long;
use Socket;

my %configvalues = ();

&readoptions();
$configvalues{'help'} && exit;

$configvalues{version} = '1.4';
$oldadmin_included = "Included in Asgard";
$none = "<none>";

checking('db-host', sub { defined gethostbyname($configvalues{'db-host'}) || die "$configvalues{'db-host'} does not resolve\n"; });
checking('db-admin-user', sub { $configvalues{'db-admin-user'} || die "db-admin-user is empty\n"; });
checking('db-user', sub { $configvalues{'db-user'} || die "db-user is empty\n"; });
checking('host', sub { defined gethostbyname($configvalues{host}) || die "$configvalues{host} does not resolve\n"; });

checking('port', sub { ($configvalues{port} =~ /^[0-9]+$/) || die "port '$configvalues{port}' is invalid\n" });
if ($configvalues{port} != 80) { $configvalues{'listen-port-number'} = "Listen $configvalues{port}"; } else { $configvalues{'listen-port-number'} = ''; }

checking('db', sub { $configvalues{db} || die "db is empty\n"; });
checking('blobdir', sub { -d $configvalues{blobdir} || die "'$configvalues{blobdir}' is not a valid directory\n"; });

checking('admin-user', sub { $configvalues{'admin-user'} || die "admin-user is empty\n"; });
checking('admin-pass', sub { $configvalues{'admin-pass'} || die "admin-pass is empty\n"; });
$configvalues{'admin-pass'} = "**" .  $configvalues{'admin-pass'};

if (!$configvalues{pagecache}) { $configvalues{pagecache} = $none; }
checking('pagecache', sub {
   if ($configvalues{pagecache} ne $none && ! -d $configvalues{pagecache}) {
      die "'$configvalues{pagecache}' is not a valid directory\n";
   }
});
if ($configvalues{pagecache} eq $none) {
   $configvalues{pagecache} = "";
} else {
   $configvalues{pagecache} = "MidgardPageCacheDir " . $configvalues{pagecache};
}

if ($configvalues{ip} eq '') {
   my $tmp = inet_aton($configvalues{host});
   if (defined $tmp) { $configvalues{ip} = inet_ntoa($tmp); }
}
checking('ip', sub { ($configvalues{ip} =~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) || die "ip '$configvalues{ip}' is invalid\n" });

checking('midgard', sub {
   $location = '';
   foreach ('/usr', '/usr/local', $configvalues{midgard}) {
      if (-e "$_/share/midgard") { $location = $_; }
   }
   $location || die "Cannot find installation location of midgard\n";
   $configvalues{midgard} = $location;
});
$configvalues{'midgard-data'} = "$configvalues{midgard}/share/midgard";
$configvalues{'midgard-bin'} = "$configvalues{midgard}/bin";

checking('apxs', sub {
   if (!$configvalues{apxs}) {
      foreach (split(/:/, $ENV{PATH})) {
         if (-e "$_/apxs") { $configvalues{apxs} = "$_/apxs"; }
      }
   }
   -e $configvalues{apxs} || die "Cannot find apxs\n";

   my $libexecdir=`$configvalues{apxs} -q LIBEXECDIR`;
   chomp $libexecdir;

   if ($libexecdir eq '') {
      print "Your apxs seems to be broken (CFG_LIBEXECDIR not defined)\nAssuming CFG_LIBEXECDIR to /etc/httpd/modules\n";
      $libexecdir = "/etc/httpd/modules";
   }
   $configvalues{'rootfile-php3'} = "$libexecdir/midgard-root.php3";
   $configvalues{'rootfile-php4'} = "$libexecdir/midgard-root.php";
});

checking('apache-user', sub { (defined getpwnam($configvalues{'apache-user'})) || die "User '$configvalues{'apache-user'}' does not exist\n"; });
checking('apache-group', sub {
	# seems to be a common case
	if ($configvalues{'apache-group'} eq "") { $configvalues{'apache-group'} = $configvalues{'apache-user'}; }
	(defined getgrnam($configvalues{'apache-group'})) || die "Group '$configvalues{'apache-group'}' does not exist\n";
});

checking('asgard', sub { checkvalues($configvalues{asgard}, 'yes', 'no'); });
checking('asgard-ru', sub { checkvalues($configvalues{'asgard-ru'}, 'yes', 'no'); });

if ($configvalues{asgard} eq 'yes') { $configvalues{adminsite}=$oldadmin_included; }
checking('adminsite', sub { checkvalues($configvalues{adminsite}, 'yes', 'no', $oldadmin_included); });
checking('lang', sub { checkvalues($configvalues{lang}, 'en', 'ru'); });
if ($configvalues{lang} eq 'en') { $configvalues{parser} = 'latin1'; } else { $configvalues{parser} = 'russian'; }
if ($configvalues{'asgard-ru'} eq 'yes') { $configvalues{parser} = 'russian'; }

checking('php', sub { checkvalues($configvalues{php}, '3', '4'); });
if ($configvalues{php} == 3) {
   $configvalues{'php3-comment'} = "";
   $configvalues{'php4-comment'} = "# ";
   $configvalues{'php-command-prefix'} = "php3_";
} else {
   $configvalues{'php3-comment'} = "# ";
   $configvalues{'php4-comment'} = "";
   $configvalues{'php-command-prefix'} = "php_value ";
}

checking('install', sub { checkvalues($configvalues{install}, 'new', 'upgrade'); });

if ($configvalues{asgard} eq 'yes') { $configvalues{adminsite}=$oldadmin_included; }

open F, ">config.cache";
print F "\%configvalues = (\n";
foreach (@configuration) {
	$key = $$_[0];
	$key =~ s/=.*//;
	print F "\t", '"', quotemeta($key), '" => "',
		quotemeta($configvalues{$key}), '",', "\n";
}
print F ");\n";
close F;

print "Generating install files, please wait...\n";
output('dbinstall', 'midgard-data.conf', 'mysql-db.sql', 'mysql-user.sql', 'midgard-ru.xml', 'midgard-en.xml');
system "chmod 0700 dbinstall";
system "chmod 0600 midgard-data.conf mysql-db.sql mysql-user.sql config.cache midgard-ru.xml midgard-en.xml";
system "chown $> dbinstall midgard-data.conf mysql-db.sql mysql-user.sql config.cache midgard-ru.xml midgard-en.xml";


########################## UTILS ################################################

sub readoptions
{
	if (-f './config.cache') {
		print STDERR "Loading config.cache...\n";
		eval `cat ./config.cache`;
	}

   foreach (@configuration) {
      ($option, $default, $help) = @{$_};
      if (length($option) > $longest) { $longest = length($option); }

      $option =~ s/=.*//;
      $options{"with-$option:s"} = \&handle_option;
      if (! defined $configvalues{$option}) {
			$configvalues{$option} = $default;
		}
      $optionhelp{$option} = $help;
   }

   foreach (@configuration) {
      ($option, $default, $help) = @{$_};
      $helptext .= sprintf("--with-%-${longest}s     $help\n", $option);
   }

   GetOptions('verbose' => \$verbose, 'help' => \&help, %options);
}

sub handle_option
{
my ($name, $value) = @_;

   $name =~ s/^with-//;
   if ($value) { $configvalues{$name} = $value; }
}

sub help
{
   $configvalues{'help'} = 'yes';
   die $helptext;
}

sub checkvalues
{
my $answer = shift;
my @valid = @_;
my $o, $h;

   foreach (@valid) {
      ($answer eq $_) && return;
   }

   if ($answer) { print "unexpected answer '$answer'.\n"; }
   else { print "this option requires a value.\n"; }
   print "Valid options are: ", join(', ', @valid), "\n";
   exit(1);
}

sub checking
{
my ($option, $sub) = @_;

   print STDERR "Checking for $optionhelp{$option}... ";
   &$sub();
   print $configvalues{$option}, "\n";
}

sub showoptions
{
my ($option, $default, $help);

   foreach (@configuration) {
      ($option, $default, $help) = @{$_};
      $option =~ s/=.*//;
      print "$option => $configvalues{$option}\n";
   }
}

sub output
{
my @files = @_;
my %replace;
my ($key, $value);
my $line;

   while (($key, $value) = each(%configvalues)) {
      $key =~ s/-/_/g;
      $key = uc $key;

      $value =~ s/([$\\"])/\\$1/g;

      $replace{$key} = $value;
      $verbose && print "Replacing \@$key\@ with '$value'\n";
   }

   foreach (@files) {
      open I, "<$_.in";
      open O, ">$_";
      while ($line = <I>) {
         foreach (keys %replace) {
            $line =~ s/\@$_\@/$replace{$_}/g;
         }
         print O $line;
      }
      close I;
      close O;
   }
} 
