#!/bin/php
<?php
/* There are possibilities, that update_maintain_deps.php could not be solve :( - so we must install useflag-settings before! */

get_update_ebuilds();

function get_update_ebuilds_by_world() {
    $itsdesktop=false;
    $file = file("/var/lib/portage/world");
    foreach($file as $pkg){
        $pkg = trim($pkg);
        if(str_contains($pkg,"virtual/pw-basic-desktop-")){
            $itsdesktop=true;
        }
    }
    $addpkgs=array();
    if($itsdesktop){
        $addpkgs[]="app-portage/pw-cfg-portage-systemandprofile-desktop";
    }
    return($addpkgs);
}

function get_update_ebuilds(){
    #$exec = shell_exec("emerge --update --deep --newuse --with-bdeps=y -pv @world 2>&1"); // old, without bdeps is also okay...
    #$exec = shell_exec("emerge --update --deep --newuse -pv @world 2>&1");
    $exec = shell_exec("emerge --update --deep --newuse --autounmask-backtrack=y -pv @world 2>&1"); // now including --autounmask-backtrack, so it did not break backtracking, if necessary use-change is found - we exactly want this!

    // Add additional packages if resolving of first command breaks
    $world_pkgs = get_update_ebuilds_by_world();
    if(count($world_pkgs)>0) {
        $exec .= shell_exec("emerge --update -pv " . join(" ", $world_pkgs) . " 2>&1");
    }

    $ebuilds = find_ebuilds($exec);
    if(count($ebuilds)>0){
	$pkgs=array();
    if(count($ebuilds)>0) {
        $buildarr = create_build_arr($ebuilds);
        foreach ($buildarr["builds"] as $pkg => $useflags) {
            if (substr($pkg, 0, 27) == "app-portage/pw-cfg-portage-") {
                $pkgs[] = $pkg;
            }
        }
    }

    if(count($pkgs)<1){
      echo "No outstanding useflag updates, nothing todo :)\r\n";
      exit;
    }
    
	echo "Found the following ebuilds/binaries should be installed before to pretend useflag issues:\r\n";
	foreach($pkgs as $pkg){
		echo "- ".$pkg."\r\n";
	}
	echo "\r\n";
	
	echo "Calling in 5s: ";
	$cmd = "emerge --oneshot";
	foreach($pkgs as $pkg){
        $cmd .= " =" . $pkg;
	}
	echo $cmd."\r\n";
	
	sleep(5);
        $retcode=-1;
	passthru($cmd,$retcode);
        if($retcode!=0){
                echo "\r\nRETURN was not 0... try again on a per pkg base...\r\n";
        	foreach($pkgs as $pkg){
        	    $cmd="emerge --oneshot =".$pkg;
        	    echo "Calling in 5s: ";
        	    echo $cmd."\r\n";
        	    sleep(5);
	            passthru($cmd);
        	}
        }
	
	echo "\r\n\r\nDONE!\r\n";
	exit;
    }
    else{
	echo "No outstanding useflag updates, nothing todo :)\r\n";
	exit;
    }
}
function create_build_arr($ebuilds){
    $builds=array();
    $buildstrs=array();
    foreach($ebuilds as $ebuild){
	$exp = explode("]",$ebuild);
	$prog = trim($exp[1]);
	$progs = explode(" ",$prog);
	$prog = $progs[0];
	
	unset($exp[0]);
	unset($exp[1]);
	
	$flags = $progs;
	unset($flags[0]);
	$flags=join(" ",$flags)."]".join("]",$exp);
	$flags = split_after_space($flags);
	$useflags=array();
	foreach($flags as $cat=>$flagarr){
	    foreach($flagarr as $flag){
		$flag = str_replace("(","",$flag);
		$flag = str_replace(")","",$flag);
		if(substr($cat,-1)=="=") $cat=substr($cat,0,-1);
		if(substr($flag,-1)=="%") $flag=substr($flag,0,-1);
		if(substr($flag,-1)=="*") $flag=substr($flag,0,-1);
		if($cat=="USE"){
		    $useflags[]=$flag;
		}
		else{
                    if(substr($flag,0,1)=="-"){
                        $useflags[]="-".strtolower($cat)."_".substr($flag,1);
                    }
                    else{
                        $useflags[]=strtolower($cat)."_".$flag;
                    }

		}
	    }
	}

	$buildstr="emerge --oneshot =".$prog;
	$builds[$prog]=$useflags;
	$buildstrs[]=$buildstr;
    }
    return(array("emerge_str"=>$buildstrs,"builds"=>$builds));
}
function split_after_space($flags){
    $buf_group="";
    $buf_flag="";

    $ret_flags=array();

    $in_str=false;
    $in_bracked=false;
    //echo "Search Useflags for: ".$flags.":\r\n";
    for($i=0;$i<strlen($flags);$i++){
	$char = substr($flags,$i,1);
	if($char=="[" && !$in_bracked){
	    $in_bracked=true;
	    continue;
	}
	elseif($char=="]" && $in_bracked){
	    $in_bracked=false;
	    continue;
	}
	elseif($in_bracked){
	    continue;
	}
	if($char=="\""){
	    if($in_str){
		$in_str=false;
		$ret_flags[$buf_group][]=$buf_flag;
		$buf_group="";
		$buf_flag="";
	    }
	    else{
		$in_str=true;
	    }
	    continue;
	}
	if($char==" " && $in_str){
	    $ret_flags[$buf_group][]=$buf_flag;
	    $buf_flag="";
	}
	if($char==" "){
	    continue;
	}
	
	if($in_str){
	    $buf_flag.=$char;
	}
	else{
	    $buf_group.=$char;
	}
    }
    //print_r($ret_flags);
    //echo "\r\n";
    return($ret_flags);
}


function find_ebuilds($txt){
    $ebuilds=array();
    $txt = explode("\n",$txt);
    foreach($txt as $line){
        if(substr($line,0,7)=="[ebuild"){
	    $ebuilds[]=trim($line);
	}
        if(substr($line,0,7)=="[binary"){
	    $ebuilds[]=trim($line);
	}
    }
    return($ebuilds);
}
