#!/usr/bin/perl -w

use strict;
use warnings;
use IServ::DB;
use Time::Local;

my $OLDCFG = "/old/opt/iserv/idesk/rooms/admin/config.inc.rpmsave";
my $NEWCFG = "/usr/share/iserv/www/inc/mod_room-reservation/config.inc";

my @tsbegin;
my @tsend;
my @tsbeginold;
my @tsendold;
my @allowedgroups;
my @admingroups;
my $restrictaccess = 0;
my $showweekend = 0;
my $showlessons = 1;

# convert the config file
open IN, "<", $OLDCFG or die "ERROR: old config file could not be opened: $!";
while(<IN>) {
  # skip unused variables
  if(/\$cfgRooms\[(\"LogOnInsert\"|\'LogOnInsert\')\]/) {
  } elsif(/\$cfgRooms\[(\"OldBookings\"|\'OldBookings\')\]/) {
  } elsif(/\$cfgRooms\[(\"ShowClassEdit\"|\'ShowClassEdit\')\]/) {
  } elsif(/\$cfgRooms\[(\"ClassEditText\"|\'ClassEditText\')\]/) {

  # AbsTime is now named ShowLessons
  } elsif(/\$cfgRooms\[(\"AbsTime\"|\'AbsTime\')\]\s*=\s*(true|false|0|1)\s*/) {
    print "AbsTime is $2\n";
    $showlessons = ($2 eq "true" or $2 eq "1") ? 1 : 0; 
  
  # ShowWeekend
  } elsif(/\$cfgRooms\[(\"ShowWeekend\"|\'ShowWeekend\')\]\s*=\s*(true|false|0|1)/) {
    print "ShowWeekend is $2\n";
    $showweekend = ($2 eq "true" or $2 eq "1") ? 1 : 0;

  # timeslice beginnings
  } elsif(/\$cfgRooms\[(\"TimeslicesBegin\"|\'TimeslicesBegin\')\]\s*=\s*array\s*\(/) {
    print "processing timeslice beginnings...\n";
    while(<IN>) {
      if(/\);/) {
        last;
      } else {
        /\s*(\d)\s*=>\s*[\'\"](\d\d?):(\d\d)[\'\"]\s*/;
        my $hr = $2;
        $hr = "0$hr" if length $hr < 2;
        push @tsbeginold, "$hr:$3:00";
        push @tsbegin, Time::Local::timelocal 0, $3, $hr, 1, 0, 1970;
        print "  found beginning: $hr:$3\n";
      }
    }

  # timeslice endings
  } elsif(/\$cfgRooms\[(\"TimeslicesEnd\"|\'TimeslicesEnd\')\]\s*=\s*array\s*\(/) {
    print "processing timeslice endings...\n";
    while(<IN>) {
      if(/\);/) {
        last;
      } else {
        /\s*(\d)\s*=>\s*[\'\"](\d\d?):(\d\d)[\'\"]\s*/;
        my $hr = $2;
        $hr = "0$hr" if length $hr < 2;
        push @tsendold, "$hr:$3:00";
        push @tsend, Time::Local::timelocal 0, $3, $hr, 1, 0, 1970;
        print "  found ending: $hr:$3\n";
      }
    }
  
  # add rooms to the database, if they do not exist yet
  } elsif(/\$cfgRooms\[(\"Rooms\"|\'Rooms\')\]\s*=\s*array\s*\(/) {
    print "processing rooms...\n";
    while(<IN>) {
      if(/\);/) {
        last;
      } else {
        /\s*\d\s*=>\s*((\'([^\']*)\')|(\"([^\"]*)\"))\s*/;
        my $sqlval = IServ::DB::Val $3;
        if(IServ::DB::Rows "SELECT * FROM rooms WHERE name = $sqlval;") {
          print "  room '$3' found in database.\n";
        } else {
          print "NOTICE: room '$3' not found in database, adding it.\n";
          IServ::DB::Put "rooms", { "name" => $3 } or die $!;
        }
      }
    }

  # convert old user rights to privileges
  } elsif(/\$cfgRooms\[(\"RestrictAccess\"|\'RestrictAccess\')\]\s*=\s*(false|true|0|1)/) {
    $restrictaccess = ($2 eq "true" or $2 eq "1") ? 1 : 0;

  } elsif(/\$cfgRooms\[(\"AllowedGroups\"|\'AllowedGroups\')\]\s*=\s*array\s*\(/) {
    print "processing allowed groups...\n";
    while(<IN>) {
      if(/\);/) {
        last;
      } else {
        /\s*\d\s*=>\s*((\'([^\']*)\')|(\"([^\"]*)\"))\s*/;
        my $name = IServ::DB::Val $3;
        my @act = IServ::DB::GetArr "SELECT act FROM groups WHERE name=$name;";
        if(@act) {
          print "  found group $name.\n";
          push @allowedgroups, $act[0]{"act"};
        } else {
          print "NOTICE: group $name not found in database, ignoring it.\n";
        }
      }
    }
  
  } elsif(/\$cfgRooms\[(\"GroupsAdmin\"|\'GroupsAdmin\')\]\s*=\s*array\s*\(/) {
    print "processing admin groups...\n";
    while(<IN>) {
      if(/\);/) {
        last;
      } else {
        /\s*\d\s*=>\s*((\'([^\']*)\')|(\"([^\"]*)\"))\s*/;
        my $name = IServ::DB::Val $3;
        my @act = IServ::DB::GetArr "SELECT act FROM groups WHERE name=$name;";
        if(@act) {
          print "  found group $name.\n";
          push @admingroups, $act[0]{"act"};
        } else {
          print "NOTICE: group $name not found in database, ignoring it.\n";
        }
      }
    }
  }
}

print "converting old user rights to privileges...\n";
# change the privilege names to the right ones
if($restrictaccess) {
  foreach(@allowedgroups) {
    my $priv = "mod_roomreservation_view";
    my $act = "$_";
    my @act = IServ::DB::GetArr "SELECT act FROM privileges_assign ".
      "WHERE privilege='$priv' AND act='$act';";
    if(@act) {
      print "  group $_ is already allowed to see the bookings, ignoring it.\n";
    } else {
      IServ::DB::Put "privileges_assign", { "act" => $_,
        "privilege" => $priv } or die $!;
      print "  allowed viewing for group '$_'\n";
    }

    $priv = "mod_roomreservation_book";
    @act = "SELECT act FROM privileges_assign ".
      "WHERE privilege='$priv' AND act='$act';";
    if(@act) {
      print "  group $_ is already allowed to book, ignoring it.\n";
    } else {
      IServ::DB::Put "privileges_assign", { "act" => $_,
        "privilege" => $priv } or die $!;
      print "  allowed booking for group '$_'\n";
    }
  }
}
foreach(@admingroups) {
  my $priv = "mod_roomreservation_admin";
  my $act = "$_";
  my @act = IServ::DB::GetArr "SELECT act FROM privileges_assign ".
    "WHERE privilege='$priv' AND act='$act';";
  if(@act) {
    print "  group $_ has already adminship, ignoring it.\n";
  } else {
    IServ::DB::Put "privileges_assign", { "act" => $_,
      "privilege" => $priv } or die $!;
    print "  allowed administration for group '$_'\n";
  }
}

print "writing config file...\n";
system "touch $NEWCFG"; 
open OUT, ">", $NEWCFG or die "ERROR: new config file could not be opened: $!";
print OUT "<?php\n\$this->flushTimeslices();\n";
for(my $i = 0; $i <= $#tsbegin; $i++) {
  print OUT "\$this->addTimeslice(new mod_roomReservationTimeslice($tsbegin[$i],$tsend[$i]));\n";
}
print OUT "\$this->setShowWeekend($showweekend);\n";
print OUT "\$this->setShowLessons($showlessons);\n";
print OUT "?>";
close OUT;
close IN;

print "\nconverting the database, have a lot of fun...\n";
open IN, "cat /old/rooms.sql | iconv -f utf8 -t utf8 |" or die 
  "ERROR: the database dump could not be opened: $!\n";

# build hashes of the form "timestamp" => "timeslice" ("15:00:00" => "3")
my $i = 0;
my %tsbeginoldkeys;
my %tsendoldkeys;
foreach (@tsbeginold) {
  $tsbeginoldkeys{$_} = $i;
  $i++;
}
$i = 0;
foreach (@tsendold) {
  $tsendoldkeys{$_} = $i;
  $i++;
}

# database conversion
# insert old data and then convert them
print "importing old bookings...\n";
IServ::DB::Exec "CREATE TABLE mod_roomreservation_bookings_old (id INT NOT NULL PRIMARY KEY, room TEXT NOT NULL, date DATE NOT NULL, timebegin TIME NOT NULL, timeend TIME NOT NULL, act TEXT REFERENCES users(Act) ON DELETE CASCADE ON UPDATE CASCADE NOT NULL, class TEXT, reason TEXT NOT NULL, fixed BOOL);";
while(<IN>) {
  # rename the table
  $_ =~ s/INSERT INTO rooms/INSERT INTO mod_roomreservation_bookings_old/;
  IServ::DB::Exec($_);
}

print "converting the database...\n";
foreach(IServ::DB::GetArr("SELECT * FROM mod_roomreservation_bookings_old;")) {
  my %row = %{$_};
  IServ::DB::Put "mod_roomreservation_bookings", { "rrb_room" => $row{"room"},
    "rrb_date" => $row{"date"}, "rrb_tsfirst" => 
    $tsbeginoldkeys{$row{"timebegin"}}, "rrb_tslast" => 
    $tsendoldkeys{$row{"timeend"}}, "rrb_act" => $row{"act"}, "rrb_reason" =>
    $row{"reason"}, "rrb_interval" => $row{"fixed"} };
}

# delete old table
IServ::DB::Exec "DROP TABLE mod_roomreservation_bookings_old;";

print "done.\n";

