#!/usr/bin/env php
<?php
/**
 * Script to install a horde installation in a web-accessible directory,
 * while allowing changes made to the repository source to also be reflected
 * in the local installation.
 *
 * If run with no arguments, reads in config values from the file
 * ./install_dev.conf.
 *
 * @author   Michael Slusarz <slusarz@horde.org>
 * @category Horde
 */

require_once 'Console/Getopt.php';
$c = new Console_Getopt();
$argv = $c->readPHPArgv();
array_shift($argv);

/* Defaults */
$apps = array();
$debug = $git = $no_framework = false;
$framework = $horde_git = $static_group = $web_dir = '';
$static_mode = 0775;

if (count($argv)) {
    $options = $c->getopt2($argv, '', array('apps=', 'config=', 'debug', 'framework=', 'git', 'group=', 'hordegit=', 'mode=', 'noframework=', 'webdir='));
    if ($options instanceof PEAR_Error) {
        exit("Invalid arguments.\n");
    }

    foreach ($options[0] as $val) {
        switch ($val[0]) {
        case '--apps':
            $apps = explode(',', $val[1]);
            break;

        case '--config':
            require_once $val[1];
            break;

        case '--debug':
            $debug = (bool)$val[1];
            break;

        case '--framework':
            $framework = $val[1];
            break;

        case '--git':
            $git = (bool)$val[1];
            break;

        case '--group':
            $static_group = $val[1];
            break;

        case '--hordegit':
            $horde_git = $val[1];
            break;

        case '--mode':
            $mode = $val[1];
            break;

        case '--noframework':
            $no_framework = $val[1];
            break;

        case '--webdir':
            $web_dir = $val[1];
            break;
        }
    }
} else {
    require_once __DIR__ . '/install_dev.conf';
}

$horde_git = rtrim(ltrim($horde_git), '/ ');
$web_dir = rtrim(ltrim($web_dir), '/ ');
if (!$framework) {
    $framework = escapeshellarg($horde_git) . '/framework';
}

if ($git && ($git === true)) {
    $git = 'git fetch && ( git rebase -v origin || ( git stash && ( git rebase -v origin || echo "WARNING: Run \'git stash pop\' manually!" ) && git stash pop ) )';
}

print "EMPTYING old web directory " . $web_dir . "\n";
try {
    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($web_dir), RecursiveIteratorIterator::CHILD_FIRST);
} catch (UnexpectedValueException $e) {
    print "Old web directory not found. Creating it.";
    mkdir($web_dir);
    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($web_dir), RecursiveIteratorIterator::CHILD_FIRST);
}
while ($it->valid()) {
    if (!$it->isDot()) {
        if ($it->isLink()) {
            if ($debug) {
                print "DELETING LINK: " . $it->key() . "\n";
            }
            unlink($it->key());
        } elseif ($it->isDir()) {
            if ($debug) {
                print "DELETING DIR: " . $it->key() . "\n";
            }
            rmdir($it->key());
        } elseif ($it->isFile()) {
            if ($debug) {
                print "DELETING FILE: " . $it->key() . "\n";
            }
            unlink($it->key());
        }
    }
    $it->next();
}

if (!empty($git)) {
    print "\nUPDATING repository\n";
    system('cd ' . $horde_git . ';' . $git);
}

print "\nLINKING horde\n";
file_put_contents($horde_git . '/horde/config/horde.local.php', "<?php if (!defined('HORDE_BASE')) define('HORDE_BASE', '$web_dir'); ini_set('include_path', '{$web_dir}/libs' . PATH_SEPARATOR . ini_get('include_path'));");
foreach (new DirectoryIterator($horde_git . '/horde') as $it) {
    if ($it->isDot()) {
        continue;
    }
    if ($it->isDir()) {
        if (strpos($it->getPathname(), $horde_git . '/horde/js') !== false) {
            if ($debug) {
                print 'CREATING DIRECTORY: ' . $web_dir . '/' . $it . "\n";
            }
            mkdir($web_dir . '/' . $it);
            foreach (new DirectoryIterator($horde_git . '/horde/' . $it) as $sub) {
                if ($sub->isDot()) {
                    continue;
                }
                if ($debug) {
                    if ($sub->isDir()) {
                        print 'LINKING DIRECTORY: ' . $web_dir . '/' . $it . '/' . $sub . "\n";
                    } else {
                        print 'LINKING FILE: ' . $web_dir . '/' . $it . '/' . $sub . "\n";
                    }
                }
                symlink($sub->getPathname(), $web_dir . '/' . $it . '/' . $sub);
            }
        } else {
            if ($debug) {
                print 'LINKING DIRECTORY: ' . $web_dir . '/' . $it . "\n";
            }
            symlink($it->getPathname(), $web_dir . '/' . $it);
        }
    } else {
        if ($debug) {
            print 'LINKING FILE: ' . $web_dir . '/' . $it . "\n";
        }
        symlink($it->getPathname(), $web_dir . '/' . $it);
    }
}

if (file_exists($web_dir . '/static')) {
    echo 'Setting static directory permissions...';
    chmod($web_dir . '/static', $static_mode);
} else {
    echo 'Creating static directory...';
    mkdir($web_dir . '/static', $static_mode);
}

if ($static_group) {
    chgrp($web_dir . '/static', $static_group);
}

function link_app($app)
{
    print "LINKING " . $app . "\n";
    if (!symlink($GLOBALS['horde_git'] . '/' . $app, $GLOBALS['web_dir'] . '/' . $app)) {
        echo 'Cannot link ' . $GLOBALS['web_dir'] . '/' . $app . ' to '
            . $GLOBALS['horde_git'] . '/' . $app . "\n";
    }
    file_put_contents($GLOBALS['horde_git'] . '/' . $app . '/config/horde.local.php', '<?php define(\'HORDE_BASE\', \'' . $GLOBALS['web_dir'] . '\');');
}

print "\nLINKING applications to web directory " . $web_dir . "\n";
if ($apps) {
    foreach ($apps as $app) {
        if ($app == 'horde') {
            continue;
        }
        if (file_exists($horde_git . '/' . $app)) {
            link_app($app);
        }
    }
} else {
    foreach (new DirectoryIterator($horde_git) as $it) {
        if (!$it->isDot() && $it->isDir() && $it != 'horde' &&
            is_dir($it->getPathname() . '/config')) {
            link_app($it);
        }
    }
}

if (!$no_framework) {
    print "\nLINKING framework\n";
    mkdir($web_dir . '/libs');
    system(__DIR__ . '/install_framework --src ' . $framework . ' --dest ' . escapeshellarg($web_dir . '/libs') . ' --horde ' . escapeshellarg($web_dir));
}
