#!/usr/bin/perl -w
#
# phpwiki configuration file migration script
# index.php => config.ini
#
# Author:   Matt Brown <matt@mattb.net.nz>,
#           Reini Urban <rurban@x-ray.at>
#
# Run this script without any arguments for usage information.
#
# This script 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.
#
# PhpWiki 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 PhpWiki; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

# Store the values
# In the form $values{$varname} = (value, comment_state)
# Where value is the value in index.php and comment_state indicates
# whether the line was commented or not
use strict;
use warnings;

my %values = ();

# Check we got a index.php to read from
if ($#ARGV < 0) {
  print "Usage: ./phpwiki-migrate-config <../path/to/index.php>\n\n";
  print "Takes an old style (<= 1.3.9) index.php configuration file\n";
  print "for phpwiki and outputs a new style (>= 1.3.10) ./config.ini\n";
  print "configuration file for phpwiki, based on a set of\n";
  print "./config-{dist,default}.ini files.\n";
  print "\n";
  print "The values extracted from the old config file will be\n";
  print "substituted into a new config.ini file as necessary. Commented\n";
  print "directives in index.php will remain commented in config.ini\n";

  exit 1;
}

# Read in values from index.php
my $infile = shift;
open INDEXPHP, "< $infile" or die "Cannot read $infile: $!\n";
my $inifile     = "config.ini";
my $distfile    = "config-dist.ini";
my $defaultfile = "config-default.ini";
die "$inifile already exists.\n" if -e $inifile;

# Write out config.ini, substituting values as needed
open OUT, "> $inifile"
  or die "Failed to write $inifile. $!\n";
open CONFDIST, "< $distfile"
  or die "Failed to open $distfile: $!\n";
open CONFDEFAULT, "< $defaultfile"
  or die "Failed to open $defaultfile: $!\n";

my $epmaj = 0;
my $epmin = 0;

while (<INDEXPHP>) {
  my ($name, $value) = ('','');
  # Check if the line starts with a comment (# or / char)
  my $is_comment = /^[#\/]/;
  if (!$is_comment) {
    $is_comment = 0;
  }

  # Process expire parameters
  if (/'keep'/) {
    ($value) = (/'keep'\s*=>\s*(.*)\)/);
    if ($epmaj) {
      $name = "MAJOR_KEEP";
    } elsif ($epmin) {
      $name = "MINOR_KEEP";
    }
  }
  $epmaj = 0;
  $epmin = 0;

  # Skip some known bad options
  if (/ALLOW_LDAP_LOGIN/) {
    next;
  } elsif (/ALLOW_IMAP_LOGIN/) {
    next;

    # Process defined values
  } elsif (/define\s*\(/) {
    # Extract the name of the define and the value of it
    ($name, $value) = (/define\s*\(\s*['"](.*)['"]\s*,\s*['"]*([^'"]*)['"]*\s*\)/);

    # Process PHP variable values
  } elsif (/HTML_DUMP_SUFFIX\s*=/) {
    ($name, $value) = (/\$(\w*)\s*=\s*['"](.*)['"];\s*/);
  } elsif (/AllowedProtocols\s*=/) {
    ($value) = (/\$\w*\s*=\s*(.*);\s*/);
    $name = "ALLOWED_PROTOCOLS";
  } elsif (/InlineImages\s*=/) {
    ($value) = (/\$\w*\s*=\s*(.*);\s*/);
    $name = "INLINE_IMAGES";
  } elsif (/WikiNameRegexp\s*=/) {
    ($value) = (/\$\w*\s*=\s*(.*);\s*/);
    $name = "WIKI_NAME_REGEXP";

    # Process arrays that need to be converted
  } elsif (/GenericPages\s*=/) {
    ($value) = (/\$\w*\s*=\s*array\((.*)\)/);
    $name = "DEFAULT_WIKI_PAGES";
    $value =~ s/[" ]//g;
    $value =~ s/,/:/g;
    $value = "\"$value\""
  } elsif (/keywords\s*=/) {
    ($value) = (/\$\w*\s*=\s*array\((.*)\)/);
    $name = "KEYWORDS";
    $value =~ s/[" ]//g;
    $value =~ s/,/:/g;
    $value = "\"$value\""

      # Process database paramters
  } elsif (/'dbtype'\s*=>/) {
    ($value) = (/'dbtype'\s*=>\s*['"](.*)['"]/);
    $name = "DATABASE_TYPE";
  } elsif (/'dsn'\s*=>/) {
    ($value) = (/'dsn'\s*=>\s*['"](.*)['"]/);
    $name = "DATABASE_DSN";
  } elsif (/'timeout'\s*=>/) {
    ($value) = (/'timeout'\s*=>\s*(.*)\s*,/);
    $name = "DATABASE_TIMEOUT";
  } elsif (/'db_session_table'\s*=>/) {
    ($value) = (/'db_session_table'\s*=>\s*['"](.*)['"]/);
    $name = "DATABASE_SESSION_TABLE";
  } elsif (/'prefix'\s*=>/) {
    ($value) = (/'prefix'\s*=>\s*['"](.*)['"]/);
    $name = "DATABASE_PREFIX";
  } elsif (/'directory'\s*=>/) {
    ($value) = (/'directory'\s*=>\s*['"](.*)['"]/);
    $name = "DATABASE_DIRECTORY";
  } elsif (/'dba_handler'\s*=>/) {
    ($value) = (/'dba_handler'\s*=>\s*['"](.*)['"]/);
    $name = "DATABASE_DBA_HANDLER";

    # Process Expire Parameters
  } elsif (/\$ExpireParams\['major'\]\s*=/) {
    ($value) = (/'max_age'\s*=>\s*(.*),/);
    $name = "MAJOR_MAX_AGE";
    $epmaj = 1;
  } elsif (/\$ExpireParams\['minor'\]\s*=/) {
    ($value) = (/'max_age'\s*=>\s*(.*),/);
    $name = "MINOR_MAX_AGE";
    $epmin = 1;

    # Process include path
  } elsif (/ini_set.*include_path'/) {
    ($value) = (/ini_set.*include_path'\s*,\s*(.*)\s*\)/);
    $name = "INCLUDE_PATH";

  }
  if ($name =~ /^$/) {
    next;
  }

  # Put it into the array
  if (exists $values{$name} && $is_comment) {
    # If we already have a value and this one is commented, skip it
    next;
  }
  #print "$name => $value ($is_comment)\n";
  $values{$name} = [$value, $is_comment];
}

close INDEXPHP;

# Print values we got
#for my $name ( keys %values ) {
#    ($value, $is_comment) = @{$values{$name}};
#    print "$name => $value";
#    if ($is_comment) { print " (commented)"; }
#    print "\n";
#}

select OUT;
# Write out migration header
print "; phpwiki 1.3.x configuration automatically generated from $infile\n";
print "; by migrate-phpwiki-config script\n\n";

while (<CONFDIST>) {
  # Look for config var lines
  if (!/\w* = /) {
    print $_;
    next;
  }
  my ($name, $value, $is_comment);
  ($name) = (/(\w*) = /);
  if (!exists $values{$name}) {
    print $_;
    next;
  }
  ($value, $is_comment) = @{$values{$name}};
  if ($is_comment) {
    print "; $name = $value\n";
  } else {
    print "$name = $value\n";
  }
}

close OUT;
close CONFDIST;
close CONFDEFAULT;
