#!/bin/php
<?php
ensure_dirs();

if(isset($argv[1]) && $argv[1]=="daemon"){
    main_daemon();
    exit(0);
}
elseif(isset($argv[1]) && $argv[1]=="oneshot"){
    if(isset($argv[2]) && $argv[2]=="nowait"){
    main_do(true);
    }
    else{
	main_do(false);
    }
    exit(0);
}
else{
    echo "Usage: update_ensure_downstream.php daemon|oneshot [nowait]\r\n";
    exit(1);
}

function main_daemon(){
    global $logger_fp;
    while(true){
	// Do it endless
	$logger_fp = fopen("/var/log/portage-updater/ensure_downstream/".date("Y-m-d-H-i-s").".log","a");
	ob_start("callback_pass_str",20);
	passthru("update_ensure_downstream.php oneshot");
	ob_end_flush();
	fclose($logger_fp);
	sleep(60);
    }
}
function callback_pass_str($buffer){
    global $logger_fp;
    fwrite($logger_fp,$buffer);
    return($buffer);
}
function update_cache_every8h(){
    global $last_cache_updated;
    if(!isset($last_cache_updated)){
        $last_cache_updated=0;
    }
    if((time()-$last_cache_updated)>(60*60*8)){
        echo "Update cache...\r\n";
        passthru("update_status.php update_cache_only");
        $last_cache_updated=time();
    }
}

function main_do($nowait=false){
    $printinfo=false;
    if($nowait){
	echo "no waiting... direct proceed...\r\n";
    }
    else{
	while(true){
	    $waittime = get_waittime();
	    if($waittime>0){
            update_cache_every8h();
		echo date("d.m.Y H:i:s").": we must wait ".$waittime." seconds before proceeding...\r\n";
		if(!$printinfo){
		    echo "If you don't want to wait, you can call:\r\n";
		    echo "- eix-sync / emerge --sync / emergesync.php target\r\n";
		    echo "- update_maintain_deps.php\r\n";
		    echo "- update_buildhost_compile.php\r\n";
            echo "- update_prefetch_binpkgs_delta.php\r\n";
            echo "- update_status.php update_cache_only\r\n";
		    #echo "- emerge --update --deep --newuse --rebuilt-binaries --fetchonly world\r\n";
		    echo "now waiting...\r\n";
		    $printinfo=true;
		}
		$waittime = min(3600,$waittime);
		sleep($waittime);
	    }
	    else{
		break;
	    }
	}
    }
    echo "Claim flock... ";
    $fp_lock = fopen("/var/run/update_ensure_downstream_oneshot.lock","w+");
    flock($fp_lock,LOCK_EX);
    echo "done\r\n";
    echo "Syncing...\r\n";
    passthru("emergesync.php target");
    echo "Update cache...\r\n";
    passthru("update_status.php update_cache_only");
    if(!$nowait){
	echo "For DEBUGGING - Print emerge Update Informations...";
	passthru("emerge --update --deep --newuse --rebuilt-binaries -pv world");
    }
    echo "update_maintain_deps...\r\n";
    passthru("update_maintain_deps.php");
    echo "Push buildhost information...\r\n";
    $retcode=-1;
    passthru("update_buildhost_compile.php",$retcode);
    die_if_ebuilds($fp_lock);
    echo "Ensure up2date portage...\r\n";
    if($retcode==6){
	// New binaries successfully available
	echo "New binaries successfully available, do fetchonly...\r\n";
	echo "CALL update_prefetch_binpkgs_delta.php...\r\n";
	passthru("update_prefetch_binpkgs_delta.php");
        die_if_ebuilds($fp_lock);
	#echo "CALL emerge --update --deep --newuse --rebuilt-binaries --fetchonly world...\r\n";
	#passthru("emerge --update --deep --newuse --rebuilt-binaries --fetchonly world");
    }
    elseif($retcode==5){
	// Nothing todo, do fetch binaries...
	echo "Nothing done on buildhost, do fetchonly...\r\n";
	echo "CALL update_prefetch_binpkgs_delta.php...\r\n";
	passthru("update_prefetch_binpkgs_delta.php");
        die_if_ebuilds($fp_lock);
	#echo "CALL emerge --update --deep --newuse --rebuilt-binaries --fetchonly world...\r\n";
	#passthru("emerge --update --deep --newuse --rebuilt-binaries --fetchonly world");
    }
    echo "done, updating cache\r\n";
    passthru("update_status.php force_update");
    echo "done all!\r\n";
    set_flag();
    fclose($fp_lock);
}
function die_if_ebuilds($fp_lock){
        $exec = shell_exec("emerge --update --deep --newuse -pv world");
        if(strpos($exec,"[ebuild")!==false){
                echo "There are ebuilds left (emerge --update --deep --newuse -pv world), dont go further... break!\r\n";
                echo "Details:\r\n";
                passthru("emerge --update --deep --newuse -pv world");
                echo "releasing lock...\r\n";
                fclose($fp_lock);
                echo "Now sleeping for 2 hours... ";
                for($i=0;$i<120;$i++){
                        sleep(60);
                }
                echo "sleep done!\r\n";
                exit(1);
        }
        else{
                echo "No ebuilds left (emerge --update --deep --newuse -pv world)... go further...\r\n";
        }
}
function ensure_dirs(){
    if(!file_exists("/var/lib/portage-updater")){
	@mkdir("/var");
	@mkdir("/var/lib");
	@mkdir("/var/lib/portage-updater");
    }
    if(!file_exists("/var/log/portage-updater/ensure_downstream")){
	@mkdir("/var");
	@mkdir("/var/log");
	@mkdir("/var/log/portage-updater");
	@mkdir("/var/log/portage-updater/ensure_downstream");
    }
    if(!file_exists("/var/lib/portage-updater/last-ensure_downstream")){
	touch("/var/lib/portage-updater/last-ensure_downstream",time()-(30*24*60*60));
    }
}
function set_flag(){
    $rand = rand(0,60*60*8); // 8 Stunden Variablität
    touch("/var/lib/portage-updater/last-ensure_downstream",time()-$rand);
}
function get_waittime(){
    $mtime = filemtime("/var/lib/portage-updater/last-ensure_downstream");
    $ntime = time();
    $delta = $ntime-$mtime;
    if(on_ac_power()){
        $overtime = $delta-(60*60*24);    // 1 Tag Default Delta - 8h Variablität - on Power
    }
    else{
        $overtime = $delta-(60*60*24*14);    // 14 Tag Default Delta - 8h Variablität - on Battery
    }
    $overtime*=-1;
    if($overtime<0)$overtime=0;
    return($overtime);
}
function on_ac_power(){
    $onac = pwpowerstates::check_if_on_ac_power();
    if($onac){
        echo "on_ac_power()=true\r\n";
    }
    else{
        echo "on_ac_power()=false\r\n";
    }
    return($onac);
}