<?php

// WORKER_BUSY_TOO_LONG_RETRY ändert das verhalten des normalen client (download...)


function workerBusyCount($arguments){
 global $globalsettings;
 
 if (array_key_exists("top_msg_id", $arguments)) { $to_topic=$arguments["top_msg_id"]; } else $to_topic=-1;
 foreach($arguments["id"] as $m) {
  $sourceid=substr($arguments["from_peer"], 4);
  $targetid=substr($arguments["to_peer"], 4);
  $msgid=$m;
  
  $sql="select * from forwardqueue where 
         sourceid like '".pg_escape_string($globalsettings["db"]["pg_conn"], $sourceid)."%' and
         targetid = ".$targetid." and 
         msgid = ".$msgid." and 		 
         to_topic = ".$to_topic."";
  $result=pg_query($globalsettings["db"]["pg_conn"], $sql);

  $numrows=pg_num_rows($result);
  if ($numrows != 0) {
   while ($row = pg_fetch_array($result)) {
    $filetargetcheck=syncChecktargetChannel($row["width"], $row["heigth"], $row["runtime"], $row["filedate"], $row["filesize"], $targetid);
    echo $row["width"]." - ".$row["heigth"]." - ".$row["runtime"]." - ".$row["filedate"]." - ".$row["filesize"]." - ".$targetid." cover: ".$row["cover"]."\n";
    if ($filetargetcheck == -1) {
     echo $row["message"]." was not forwarded \n";
    } else { 
     echo $row["message"]." now in target channel \n";
    } // if ($filetargetcheck == -1) 
   } // while ($row = pg_fetch_array($result)) 
  } // if ($numrows != 0) 		 
 } // foreach($arguments["id"] as $m) 
} // function end


function clearForwardTable($arguments) {
 global $globalsettings;

 if (array_key_exists("top_msg_id", $arguments)) { $to_topic=$arguments["top_msg_id"]; } else $to_topic=-1;
 
 foreach($arguments["id"] as $m) {
  $sourceid=substr($arguments["from_peer"], 4);
  $targetid=substr($arguments["to_peer"], 4);
  $msgid=$m;
  $to_topic=$to_topic;  

  $sql="delete from forwardqueue where 
         sourceid like '".pg_escape_string($globalsettings["db"]["pg_conn"], $sourceid)."%' and 
         targetid = ".$targetid." and 
         msgid = ".$msgid." and 
         to_topic = ".$to_topic."";
  pg_query($globalsettings["db"]["pg_conn"], $sql);

 } // foreach($arguments["id"] as $m) 
} // function end

function made($class, $function, $arguments, $trycount=1, $return=false) {
 global $MadelineProto, $interval, $floodwait, $globalsettings, $forwardstopmsg, $floodchallange, $channelInfoNew, $systemLoad;

 try { 
  switch ($function) {
   case "getMessages":
    $return=$MadelineProto->$class->$function(channel: $arguments["channel"], id: $arguments["id"]);
   break;
   case "deleteMessages":
    $return=$MadelineProto->$class->$function(channel: $arguments["channel"], id: $arguments["id"]);
   break;
   case "getForumTopics": 
    $return=$MadelineProto->channels->getForumTopics(channel: $arguments["channel"], limit: $arguments["limit"]);
   break;
   case "getPeerDialogs":
    $return=$MadelineProto->$class->$function(peers: $arguments["peers"]);
   break;
   case "getHistory":
    if (array_key_exists("offset_id", $arguments)) {
     $return=$MadelineProto->$class->$function(peer: $arguments["peer"], offset_id: $arguments["offset_id"], limit: $arguments["limit"]);
    } else $return=$MadelineProto->$class->$function(peer: $arguments["peer"], limit: $arguments["limit"]);
   break;
   case "deleteMessages":
    $return=$MadelineProto->$class->$function(id: $arguments["id"]);
   break;
   case "forwardMessages":
    if (array_key_exists("top_msg_id", $arguments)) { 
     $MadelineProto->messages->forwardMessages(background: $arguments["background"], drop_author: $arguments["drop_author"], from_peer: $arguments["from_peer"], to_peer: $arguments["to_peer"], id: $arguments["id"], top_msg_id: $arguments["top_msg_id"]); 
    } else {
     $MadelineProto->messages->forwardMessages(background: $arguments["background"], drop_author: $arguments["drop_author"], from_peer: $arguments["from_peer"], to_peer: $arguments["to_peer"], id: $arguments["id"]); 
    } // if (array_key_exists(top_msg_id)) 

   // clear up table forwardqueue
   clearForwardTable($arguments);

   break;
   case "sendMessage":  
    $c=1; $opt="";
    foreach(array_keys($arguments) as $k) { if ($c >= 3) $opt.=$k."-"; $c++; } 
    $opt=substr($opt, 0, strlen($opt)-1);
    logger("made: ".$class."->".$function.": ".$opt);

    switch ($opt) {
        case "parse_mode": 
         $return=$MadelineProto->$class->$function(peer: $arguments["peer"], message: $arguments["message"], parse_mode: $arguments["parse_mode"]);
        break;
        case "reply_to_msg_id": 
         $return=$MadelineProto->$class->$function(peer: $arguments["peer"], message: $arguments["message"], reply_to_msg_id: $arguments["reply_to_msg_id"]);
        break;
        case "parse_mode-top_msg_id":
        case "top_msg_id-parse_mode":
         $return=$MadelineProto->$class->$function(peer: $arguments["peer"], message: $arguments["message"], reply_to_msg_id: 2147483646, top_msg_id: $arguments["top_msg_id"], parse_mode: $arguments["parse_mode"]);
        break;
        case "reply_to_msg_id-parse_mode": 
        case "parse_mode-reply_to_msg_id": 
         $return=$MadelineProto->$class->$function(peer: $arguments["peer"], message: $arguments["message"], reply_to_msg_id: $arguments["reply_to_msg_id"] ,parse_mode: $arguments["parse_mode"]);
        break;
        default:
         $MadelineProto->$class->$function(peer: $arguments["peer"], message: $arguments["message"]);
    } // switch ($opt) 
   break;
   case "getDialogIds()": 
    $return=$MadelineProto->getDialogIds();
   break;
   case "getSelf()": 
    $return=$MadelineProto->getSelf();
   break;
   case "downloadToFile()": 
    $return=$MadelineProto->downloadToFile($arguments["downloadmedia"], $arguments["fileout"]);
   break;
   case "getPwrChat()": 
    $return=$MadelineProto->getPwrChat($arguments["peer"]);
   break;

  } // switch ($function)
  

  } catch (Exception $e) {
    $filename=explode("/", $e->getFile());
    $filename=$filename[count($filename)-1];
    
    logger("pandabot-exception: connection: ".$function." -> ".$e->getMessage());
    
    if ($e->getMessage() == "Sending on the channel failed. Did the context die?") {
     someStatsJob();
     logger("pandabot-exception: connection: ".$function." load avg: ".$systemLoad[0].", ".$systemLoad[1].", ".$systemLoad[2]); 
    } // if ($e->getMessage() == "Sending on the channel failed. Did the context die?")

/*
    if (str_contains($e->getMessage(), "FLOOD_PREMIUM_WAIT")) { // download speed restriction for non premium members
	 $timer=explode("_",$e->getMessage()); 
	 sleep($timer[3]+1);
	 $return=made($class, $function, $arguments, $trycount, $return);
	} // if (str_contains($e->getMessage(), "FLOOD_PREMIUM_WAIT")) 
*/ 
 
     if ($e->getMessage() == "RPC_SEND_FAIL" ) {
      logger("pandabot-exception: connection: ".$function." -> wait 5 seconds");
      sleep(5);
      logger("pandabot-exception: connection: ".$function." -> resend request (try: ".$trycount.")");
      $trycount++;
	  $return=made($class, $function, $arguments, $trycount, $return);
	 } // if ($e->getMessage() == "RPC_SEND_FAIL" ) 


    if (str_contains($e->getMessage(), "FLOOD_WAIT")) {
     $timer=explode("_",$e->getMessage()); 
     $floodwait=time()+$timer[2]+20;
     $calc=$timer[2]+20;
     logger("pandabot-exception: connection: ".$function." set forward interval: time()+".$calc);
     $forwardstopmsg="floodwait";
     $interval["fwdStepper"]['lastruntime']=$floodwait;

     $sql="update settings set value = '".pg_escape_string($globalsettings["db"]["pg_conn"], $floodwait)."' where variable='".pg_escape_string($globalsettings["db"]["pg_conn"], "floodwait")."';";
     pg_query($globalsettings["db"]["pg_conn"], $sql);

     $sql="update settings set value = '".pg_escape_string($globalsettings["db"]["pg_conn"], $forwardstopmsg)."' where variable='".pg_escape_string($globalsettings["db"]["pg_conn"], "forwardstopmsg")."';";
     pg_query($globalsettings["db"]["pg_conn"], $sql);

     recoverforwardqueue(1);
    } // if (str_contains($e->getMessage, "FLOOD_WAIT"))

    if ($e->getMessage() == "CHANNEL_INVALID" ) exit;

    if ($e->getMessage() == "WORKER_BUSY_TOO_LONG_RETRY") { // can be ignored? - nope
     logger("pandabot-exception: connection: ".$function." -> exception ignored");

     $channelInfoKey=substr($arguments["to_peer"], 4);

	 // clear up table forwardqueue
     clearForwardTable($arguments);
    } // if ($e->getMessage() == "WORKER_BUSY_TOO_LONG_RETRY" )
     
     if ($e->getMessage() == "MESSAGE_ID_INVALID") { // can be ignored? - nope
     logger("pandabot-exception: connection: ".$function." -> exception ignored");

     $channelInfoKey=substr($arguments["to_peer"], 4);

	 // clear up table forwardqueue
     clearForwardTable($arguments);
    } // if ($e->getMessage() == "MESSAGE_INVALID" )

    if ($e->getMessage() == "CHAT_ADMIN_REQUIRED") { // ignore 
     logger("pandabot-exception: connection: ".$function." -> exception ignored");     
    } // if ($e->getMessage() == "CHAT_ADMIN_REQUIRED")

    if ($e->getMessage() == "Request timeout") {
     if ($trycount>=100) { 
      recoverforwardqueue(1);
      logger("pandabot-exception: connection: ".$function." -> exit after: ".$trycount." trys");
      exit;
     } // if ($runcound<3) 
     logger("pandabot-exception: connection: ".$function." -> wait 30 seconds");
     sleep(30);
     logger("pandabot-exception: connection: ".$function." -> resend request (try: ".$trycount.")");
     $trycount++;
     $return=made($class, $function, $arguments, $trycount, $return);
    } // if ($e->getMessage() == "Request timeout" )
		
	if ($e->getMessage() == "This peer is not present in the internal peer database" ) {
     logger("pandabot-exception: connection: ".$function." -> set channel(".$channelInfoNew[substr($arguments["peer"], 4)]["name"].") to nook");		
	 $channelInfoNew[substr($arguments["peer"], 4)]["status"]="nook";
	 $channelInfoNew[substr($arguments["peer"], 4)]["info"]="not on channel";
	} // if ($e->getMessage() == "This peer is not present in the internal peer database" ) 
   } // catch (Exception $e) 

 return $return;
} // function end

// these inc contains:
//
// made()

