#!/usr/bin/php
<?php

/*
  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
  Copyright (C) 2003-2010  Cajus Pollmeier
  Copyright (C) 2011  FusionDirectory

  This program 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.

  This program 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 this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

define ("FD_HOME", "/usr/share/fusiondirectory");
define ("LOCALE_DIR", FD_HOME."/locale");
define ("PLUGSTATE_DIR", FD_HOME."/state");

function print_usage()
{
	?>
update-fusiondirectory - class cache, locale and documentation update for FusionDirectory
Usage: 
       update-fusiondirectory rescan-i18n     Rebuilds the translations

       update-fusiondirectory rescan-classes  Rebuilds the class list

       update-fusiondirectory rescan-guides   Rebuilds the online help 
       
       update-fusiondirectory                 Shortcut for rescan-classes and rescan-i18n
<?php
	exit (1);
}


/* Function to include all class_ files starting at a given directory base */
function get_classes($folder= ".")
{
  static $base_dir= "";
  static $result= array();

  if ($base_dir == ""){
    if ($folder == "."){
      $base_dir= getcwd();
    } else {
      $base_dir= $folder;
    }
  }

  $currdir=getcwd();
  if ($folder){
    chdir("$folder");
  }

  $dh = opendir(".");
  while(false !== ($file = readdir($dh))){

    if (preg_match("/.*\.svn.*/", $file) ||
        preg_match("/.*smarty.*/i",$file) ||
        preg_match("/.*\.tpl.*/",$file) ||
        ($file==".") ||($file =="..")){
      continue;
    }

    /* Recurse through all "common" directories */
    if (is_dir($file)){
      get_classes($file);
      continue;
    }

    /* Only take care about .inc and .php files... */
    if (!(preg_match('/\.php$/', $file) || preg_match('/\.inc$/', $file))){
      continue;
    }

    /* Include existing class_ files */
    $contents= file($file);
    foreach($contents as $line){
      $line= chop($line);
      if (preg_match('/^\s*class\s*\w.*$/', $line)){
        $class= preg_replace('/^\s*class\s*(\w+).*$/', '\1', $line);
        $result[$class]= preg_replace("%$base_dir/%", "", "$currdir/$folder/$file");
      }
    }
  }

  closedir($dh);
  chdir($currdir);

  return ($result);
}


function rescan_classes()
{
	echo "Updating class cache...\n";
	$class_mapping= get_classes("/usr/share/fusiondirectory");
	$filename= "/var/cache/fusiondirectory/class.cache";

	/* Sanity checks */
	if (!file_exists($filename) || is_writable($filename)) {

	    if (!$handle= fopen($filename, 'w')) {
		 echo "Cannot open file \"$filename\" - aborted\n";
		 exit (1);
	    }

	} else {
	    echo "File \"$filename\" is not writable - aborted\n";
	    exit (2);
	}

	fwrite ($handle, "<?php\n\$class_mapping= array(\n");
	foreach ($class_mapping as $key => $value){
	  fwrite ($handle, "                \"$key\" => \"$value\",\n");
	}
	fwrite ($handle, " );\n");

	fclose($handle);
}


function rescan_i18n()
{
	echo "Updating internationalization...\n";
	$languages= array();
	$size= strlen(LOCALE_DIR);

	/* Get all available messages.po files, sort them for languages */
	$dir= new RecursiveDirectoryIterator(LOCALE_DIR);
	$all= new RecursiveIteratorIterator($dir);
	foreach ( $all as $element ){
		if ($element->isFile() && preg_match('/\/LC_MESSAGES\/messages.po$/', $element->getPathname())){
			$lang= preg_replace('/^.*\/([^\/]+)\/LC_MESSAGES\/.*$/', '\1', $element);
			if (!isset($languages[$lang])){
				$languages[$lang]= array();
			}
			$languages[$lang][]= substr($element->getPathName(), $size+1);
		}
	}

	/* For each language, merge the target .mo to the compiled directory. */
	foreach ($languages as $language => $po_files){
		if (!is_dir("/var/cache/fusiondirectory/locale/${language}/LC_MESSAGES")){
			if (!mkdir ("/var/cache/fusiondirectory/locale/${language}/LC_MESSAGES", 0755, TRUE)){
				echo "Failed to create '/var/cache/fusiondirectory/locale/${language}/LC_MESSAGES'- aborted";
				exit (3);
			}
		}

		/* Cat all these po files into one single file */
		system ("(cd ".LOCALE_DIR." && msgcat --use-first ".implode(" ", $po_files)." > /var/cache/fusiondirectory/locale/${language}/LC_MESSAGES/messages.po)", $val);
		if ($val != 0){
			echo "Merging of message files failed - aborted";
			exit (4);
		}
		system ("(cd /var/cache/fusiondirectory/locale/${language}/LC_MESSAGES && msgfmt -o messages.mo messages.po && rm messages.po)", $val);
		if ($val != 0){
			echo "Compiling of message files failed - aborted";
			exit (5);
		}
	}

	echo "! Warning: you may need to reload your webservice!\n";
}


function rescan_guide()
{
	$master_guide= "/etc/fusiondirectory/guide.xml";
	echo "Updating Online Help Index...\n";
	$master_guide_content="<?xml version=\"1.0\"?>\n".
		"<!--\n".
		"\tWARNING:\n".
		"\tThis file is automatically generated by update-online-help.\n".
		"\tIf you want to add entries, use doc/core/guide.xml or doc/plugins/\"Appropriate Plugin Directory\"/guide.xml.\n".
		"\tThen execute update-online-help to merge them into this file.\n".
		"-->\n\n".
		"<!--\n".
		"\tThis xml file specifies which class is documented in which help file.\n".
		"\tIf isset ( \$_SESSION['current_class_for_help'] ) then open the helpfile which is\n".
		"\tspecified for this class below.\n".
		"-->\n\n".
		"<!--\n".
	       	"\t<ENTRY NAME='class name' VALUE='displayed text' PATH='path to helpfiles' FILE='path to htmlfile' />\n".
		"\tLeave blank to display message \"There is no helpfile specified for this class.\"\n".
		"-->\n".
		"<ENTRIES>\n";

	$guide= 'doc/core/guide.xml';
	if(file_exists($guide) && is_readable($guide)) {
		$master_guide_content.= file_get_contents($guide);
	}
	
	if(file_exists('doc/plugins')) {
		$plugins= scandir('doc/plugins');
		foreach($plugins as $key => $plugin) {
			if($plugin != '.' && $plugin != '..') {
				if(is_dir('doc/plugins/'.$plugin)) {
					$guide= 'doc/plugins/'.$plugin.'/guide.xml';
					if(file_exists($guide) && is_readable($guide)) {
						$master_guide_content.= file_get_contents($guide);
					}
				}
			}
		}
	}

	$master_guide_content.= "</ENTRIES>";
	
	$master_guide_content= preg_replace("/[ \t][ \t]*/", " ", $master_guide_content);

	if((file_exists($master_guide) && is_writable($master_guide)) || is_writable('doc')) {
		file_put_contents($master_guide, $master_guide_content);
	}

}

/* Fill global values */
$description= $provides= $depends= $versions= $conflicts= array();

/* Action specified? */
if ($argc < 2){
	rescan_classes();
	rescan_i18n();
	rescan_guide();
        exit (0);
}

switch ($argv[1]){
        case 'rescan-i18n':
                rescan_i18n();
                break;
        case 'rescan-classes':
                rescan_classes();
                break;
	case 'rescan-guide':
		rescan_guide();
		break;
        default:
                echo "Error: Unknow option\n\n";
                print_usage();
                break;
}


?>
