#!/usr/bin/env php
<?php
/**
 * This script imports SquirrelMail database calendars into Kronolith.
 *
 * The first argument must be a DSN to the database containing the calendar
 * and event tables, e.g.: "mysql://root:password@localhost/squirrelmail".
 *
 * Copyright 2008-2016 Horde LLC (http://www.horde.org/)
 *
 * See the enclosed file COPYING for license information (GPL). If you
 * did not receive this file, see http://www.horde.org/licenses/gpl.
 *
 * @author Jan Schneider <jan@horde.org>
 */

if (file_exists(__DIR__ . '/../../kronolith/lib/Application.php')) {
    $baseDir = __DIR__ . '/../';
} else {
    require_once 'PEAR/Config.php';
    $baseDir = PEAR_Config::singleton()
        ->get('horde_dir', null, 'pear.horde.org') . '/kronolith/';
}
require_once $baseDir . 'lib/Application.php';
Horde_Registry::appInit('kronolith', array('cli' => true, 'user_admin' => true));

// Read command line parameters.
if ($argc != 2) {
    $cli->message('Too many or too few parameters.', 'cli.error');
    $cli->writeln('Usage: kronolith-import-squirrelmail-calendar DSN');
    $cli->writeln($cli->indent('DSN are json-encoded connection parameters to the database containing the "userprefs" table. Example:'));
    $cli->writeln($cli->indent('{"adapter":"mysql","user":"root","password":"password","host":"localhost","database":"squirrelmail"}'));
    exit;
}

$db = $injector->getInstance('Horde_Db')->createDb(json_decode($argv[1]));
$default_tz = date_default_timezone_get();

// Loop through SquirrelMail calendars.
$read_stmt = 'SELECT reader_name FROM calendar_readers WHERE calendar_id = ?';
$write_stmt = 'SELECT writer_name FROM calendar_writers WHERE calendar_id = ?';
$users = $db->select('SELECT id, name, owner_name FROM calendars, calendar_owners WHERE calendars.id = calendar_owners.calendar_id');
foreach ($users as $row) {
    $user = $row['owner_name'];
    $registry->setAuth($user, array());
    $cli->message('Creating calendar ' . $row['name']);

    $kronolith_shares = $injector->getInstance('Kronolith_Shares');
    $share = $kronolith_shares->newShare($GLOBALS['registry']->getAuth(), $row['id'], $row['name']);
    $kronolith_shares->addShare($share);

    // Add permissions.
    $permissions = array();
    $result = $db->select($read_stmt, array($row['id']));
    foreach ($result as $perm_row) {
        $permissions[$perm_row[0]] = Horde_Perms::READ | Horde_Perms::SHOW;
    }
    $result = $db->select($write_stmt, array($row['id']));
    foreach ($result as $perm_row) {
        if (isset($permissions[$perm_row[0]])) {
            $permissions[$perm_row[0]] |= Horde_Perms::EDIT;
        } else {
            $permissions[$perm_row[0]] = Horde_Perms::EDIT;
        }
    }
    if (count($permissions)) {
        $perm = $share->getPermission();
        foreach ($permissions as $key => $value) {
            $perm->addUserPermission($key, $value, false);
        }
        $share->setPermission($perm);
        $share->save();
    }
}

$handle = $db->select('SELECT event_id, calendar_id, ical_raw, owner_name, prefval FROM events, event_owners LEFT JOIN userprefs ON event_owners.owner_name = userprefs.user AND userprefs.prefkey = \'timezone\' WHERE events.id = event_owners.event_key ORDER BY calendar_id, userprefs.prefval, event_owners.owner_name');
$ical = new Horde_Icalendar();
$tz = $calendar = $user = $count = null;
foreach ($handle as $row) {
    // Open calendar.
    if ($calendar != $row['calendar_id']) {
        if (!is_null($count)) {
            $cli->message('  Added ' . $count . ' events', 'cli.success');
        }
        $calendar = $row['calendar_id'];
        $cli->message('Importing events into ' . $calendar);
        $kronolith_driver->open($calendar);
        $count = 0;
    }
    // Set timezone.
    if ($tz != $row['prefval']) {
        $tz = $row['prefval'];
        date_default_timezone_set($tz ? $tz : $default_tz);
    }
    // Set user.
    if ($user != $row['owner_name']) {
        $user = $row['owner_name'];
        $registry->setAuth($user, array());
    }
    // Parse event.
    try {
        $ical->parsevCalendar($row['ical_raw']);
    } catch (Horde_Icalendar_Exception $e) {
        $cli->message('  ' . $e->getMessage(), 'cli.warning');
        continue;
    }
    $components = $ical->getComponents();
    if (!count($components)) {
        $cli->message('  No iCalendar data was found.', 'cli.warning');
        continue;
    }

    // Save event.
    $event = $kronolith_driver->getEvent();
    $event->fromiCalendar($components[0]);
    try {
        $event->save();
    } catch (Exception $e) {
        $cli->message('  ' . $e->getMessage(), 'cli.error');
        continue;
    }
    $count++;
}
if (!is_null($count)) {
    $cli->message('  Added ' . $count . ' events', 'cli.success');
}
