<?php
    // Not sure whether we need the license header here, or if this is so deep
    // in the guts of horde that this may as well be licensed same as horde.
    // Some of this certainly did get copied from horde's UI based exporter,
    // for example.

    ini_set('display_errors', true);
    ini_set('display_startup_errors', true );

    require_once '/usr/local/cpanel/base/horde/kronolith/lib/Application.php';
    Horde_Registry::appInit('kronolith', array( 'cli' => true ));

    // Random modules we are gonna need, import em
    require_once('Horde.php');
    require_once('Horde/Array.php');
    require_once('Horde/Variables.php');
    require_once('Horde/Date.php');
    require_once('Horde/Data.php');
    require_once('Horde/Db/Adapter.php');
    require_once('Horde/Core/Factory/Base.php');
    require_once('Horde/String.php');

    // Ay-yai-yai, look what these modules do -- inheritance via injection
    // where the parent module fails to load unless you load submodule first.
    // Also, holy kitchen sink, batman
    require_once('Horde/Injector/Scope.php');
    require_once('Horde/Injector/TopLevel.php');
    require_once('Horde/Injector/DependencyFinder.php');
    require_once('Horde/Injector/Binder.php');
    require_once('Horde/Injector/Binder/AnnotatedSetters.php');
    require_once('Horde/Exception.php');
    require_once('Horde/Injector/Exception.php');

    require_once('Horde/Db/Adapter/Base.php');
    require_once('Horde/Db/Adapter/Pdo/Base.php');
    require_once('Horde/Db/Adapter/Pdo/Sqlite.php');

    require_once('Horde/Injector/Binder/Implementation.php');
    require_once('Horde/Injector.php');

    // Meat of the calendar logic
    require_once('/usr/local/cpanel/base/horde/kronolith/lib/Kronolith.php');
    require_once('/usr/local/cpanel/base/horde/kronolith/lib/Factory/Driver.php');

    // Read from stdin for the calendar IDs we want.
    $stdin = fopen('php://stdin', 'r');
    $cal_ids = [];
    while( $input = trim(fgets($stdin)) ) {
        $arr = explode( ":", $input );
        $cal_ids[$arr[0]] = $arr[1];
    }

    foreach( $cal_ids as $user => $cal_id ) {
        $vars = new Horde_Variables(
            [
                'app'        => 'kronolith',
                'actionID'   => 'export',
                'all_events' => 1,
                'exportID'   => 101,
                'exportCal'  => [ "internal_$cal_id" ],
                'filename'   => "$cal_id.ics",
            ]
        );

        // Not sure why horde uses globals here, probably being dumb with their
        // classes or something. Anyways, seems necessary for now.
        global $display_calendars, $session, $calendar_manger, $registry, $injector;

        if ($vars->all_events) {
            $end = $start = null;
        } else {
            $start = new Horde_Date(
                $vars->start_year,
                $vars->start_month,
                $vars->start_day
            );
            $end = new Horde_Date(
                $vars->end_year,
                $vars->end_month,
                $vars->end_day
            );
        }
        $calendars = $vars->get('exportCal', $display_calendars);
        $events = array();
        $session->set( 'horde', 'auth/userId', $user );
        $calendar_manager = $injector->createInstance('Kronolith_CalendarsManager');
        foreach ($calendars as $calendar) {
            list($type, $cal) = explode('_', $calendar, 2);
            // Only export the internal calendars, not remote ones they added, etc.
            if( $type != 'internal' ) continue;

            // Unset cached object, as if we have that, we get old object
            //$injector->setInstance('Kronolith_Factory_Driver', null);
            //$injector->setInstance('Horde_Db_Adapter', null);

            $kronolith_driver = Kronolith::getDriver($type, $cal);
            $calendarObject = Kronolith::getCalendar($kronolith_driver);
            if (!$calendarObject ||
                !$calendarObject->hasPermission(Horde_Perms::READ)) {
                die("Permission denied\n");
            }
            $events[$calendar] = $kronolith_driver->listEvents(
                $start,
                $end,
                array(
                    'cover_dates' => false,
                    'hide_exceptions' => ($vars->exportID == Horde_Data::EXPORT_ICALENDAR)
                )
            );
        }

        $calNames = array();
        $iCal = new Horde_Icalendar();

        foreach ($events as $calevents) {
            foreach ($calevents as $dayevents) {
                foreach ($dayevents as $event) {
                    $calNames[Kronolith::getCalendar($event->getDriver())->name()] = true;
                    $iCal->addComponent($event->toiCalendar($iCal));
                }
            }
        }

        $iCal->setAttribute('X-WR-CALNAME', implode(', ', array_keys($calNames)));

        echo $iCal->exportvCalendar();
    }
    exit(0);
?>
