#!/usr/bin/php
<?php
 include("inc/include.inc.php");
 
 pg_opendb();
 

function sendMessage($sendMsg, $channelInfoKey, $msgid, $topic, $html=true ) {
 global $channelInfoNew;

 if (!$html) {
  switch ($sendMsg[0]) { // send plain messages
   case "TOCHAN": 
    if ($topic!=-1) {
     made("messages", "sendMessage", array("peer" => $channelInfoNew[$channelInfoKey]["peerid"], "message" => $sendMsg[1].generatebotmarker(), "top_msg_id" => $topic)); 
    } else {
     made("messages", "sendMessage", array("peer" => $channelInfoNew[$channelInfoKey]["peerid"], "message" => $sendMsg[1].generatebotmarker())); 
    } // if ($topic!=-1) - else
   break;
   case "TOUSER": made("messages", "sendMessage", array("peer" => $channelInfoNew[$channelInfoKey]["peerid"], "message" => $sendMsg[1].generatebotmarker(), "reply_to_msg_id" => $msgid));
   break;
  } // switch ($sendMsg[0]) 
 } else {
  switch ($sendMsg[0]) {
   case "TOCHAN": 
    if ($topic!=-1) {
     made("messages", "sendMessage", array("peer" => $channelInfoNew[$channelInfoKey]["peerid"], "message" => $sendMsg[1].generatebotmarker(), "parse_mode" => "html", "top_msg_id" => $topic)); 
    } else {
     made("messages", "sendMessage", array("peer" => $channelInfoNew[$channelInfoKey]["peerid"], "message" => $sendMsg[1].generatebotmarker(), "parse_mode" => "html")); 
    } // if ($topic!=-1) - else
   break;
   case "TOUSER": made("messages", "sendMessage", array("peer" => $channelInfoNew[$channelInfoKey]["peerid"], "message" => $sendMsg[1].generatebotmarker(), "reply_to_msg_id" => $msgid, "parse_mode" => "html"));
   break;
  } // switch ($sendMsg[0]) 
 } // if (!html) - else
} //function end


function getLastMessages($channelInfoKey, $singletarget, $startup) {
 global $lastMessagePerChan, $channelInfoNew, $globalsettings;

 if ($startup) { // build last messages array and get last 100 messages at startup
  $out=made("messages", "getPeerDialogs", array("peers" => array($channelInfoNew[$channelInfoKey]["peerid"])));

 if (array_key_exists($channelInfoNew[$channelInfoKey]["peerid"], $lastMessagePerChan)) { // update $lastMessagePerChan when key exists
  $lastMessagePerChan[$channelInfoNew[$channelInfoKey]["peerid"]]=$out['dialogs'][0]['top_message']; 
 } else $lastMessagePerChan+=array($channelInfoNew[$channelInfoKey]["peerid"] => $out['dialogs'][0]['top_message']);
  
  $out=made("messages", "getHistory", array("peer" => $channelInfoNew[$channelInfoKey]["peerid"], "limit" => 100));
  return $out;
 }

 
 $allChannels=array_keys($lastMessagePerChan);
// $globalsettings["channels"]["channeldb"]=$allChannels; -- falsche stelle getdialog...

 if ($singletarget == "1" ) {
  unset($allChannels);
  $allChannels[]=$channelInfoNew[$channelInfoKey]["peerid"]; // prevent dubletten
 }

 
 
 $getAllLastMsgID=made("messages", "getPeerDialogs", array("peers" => $allChannels));
 
 foreach($getAllLastMsgID['dialogs'] as $dialog) {


/*
 if (substr($dialog['peer'],0,4)!= "-100") {
  print_r($dialog);	 
  exit;
 }
	 
/*  switch ($dialog['peer']['_']) {
   case 'peerUser': $dialogid=$dialog['peer']['user_id']; $context="user"; 
   break;
   case 'peerChannel': $dialogid=$dialog['peer']['channel_id']; $context="chat";
   break;
  }
*/


  $dialogid=substr($dialog['peer'],4); // chat context
  if (substr($dialog['peer'],0,4)!= "-100") $dialogid=$dialog['peer']; // user context
	  
  $dialogtopmessage=$dialog['top_message'];

  foreach(array_keys($channelInfoNew) as $k) {
   if ($channelInfoNew[$k]["chanid"] == $dialogid ) {
    $lastMessageCount=$lastMessagePerChan[$channelInfoNew[$k]["peerid"]];
    if ($lastMessageCount != $dialogtopmessage) {
     if ($channelInfoNew[$k]["status"] == "ok" ) { 
      if ($channelInfoNew[$k]["from_topic_id"] != -1) { $fromprint=$channelInfoNew[$k]["chanid"].":".$channelInfoNew[$k]["from_topic_id"]; } else $fromprint=$channelInfoNew[$k]["chanid"];
      if ($channelInfoNew[$k]["mode"] == "r" ) { $printmode="readonly"; } else $printmode="interactiv";
	  switch ($channelInfoNew[$k]["mode"]) {
	   case "ir": $printmode="interactiv+request";
       break;
       case "i":  $printmode="interactiv";
       break;
       case "r":  $printmode="readonly";
       break;       
       case "a":  $printmode="admin";
       break;
	  } // switch ($channelInfoNew[$k]["mode"]) 

      logger("activity on channel: [".$channelInfoNew[$k]["name"]."] - mode: ".$printmode);
      $limit=$dialogtopmessage-$lastMessageCount+5; // get only new messages + 5 
      if ($limit>100) $limit=100; 
      $lastMessagePerChan[$channelInfoNew[$k]["peerid"]]=$dialogtopmessage; // update lastMessagePerChan
      $data=made("messages", "getHistory", array("peer" => $channelInfoNew[$k]["peerid"], "limit" => $limit));
     } else $data=false; // if ($channelInfoNew[$k]["status"] == "ok" )

     switch ($channelInfoNew[$k]["mode"]) {
	  case "ir": if ($data != false) { getAskTasks($data, $k); request($data, $k); }
      break;
      case "i": if ($data != false) getAskTasks($data, $k); 
      break;
      case "r": if ($data != false) insertData(parseData($data), $k);
      break;       
      case "a": if ($data != false) adminCommands($data, $startup);
      break;
     } // switch ($channelInfoNew[$k]["mode"]) 
    } // if ($lastMessageCount != $dialogtopmessage)
   } // if ($channelInfoNew[$k]["chanid"] == $dialogid )
  } // foreach(array_keys($channelInfoNew) as $k) 
 } // foreach($getAllLastMsgID['dialogs'] as $dialog)
} // function end

function BotCommands($askMessage, $channelInfoKey, $msgid, $infoarray, $rerun=null) {
 global $globalsettings, $channelInfoNew;

 $askcommand="!".$channelInfoNew[$channelInfoKey]["channelbotname"]." ";

 $askMessage=preg_replace("/[()]+/u", "", $askMessage); // remove brackets - [] more, when needed...  
 $askMessage=preg_replace("/^\s+|\s+$|\s+(?=\s)/u", "", $askMessage); // remove more than one space in follow 

 $splitMsg=explode(" ",$askMessage);
 foreach ($globalsettings["bot"]["botcommands"] as $botcmd) {
  if (strtolower($botcmd)==strtolower($splitMsg[1])) {
    $cmd=strtolower($botcmd);
  } 
 }

 if (array_key_exists(2,$splitMsg)) {$secarg=$splitMsg[2];} else $secarg=false;

 if (!isset($cmd)) {
  $returnMsg[0]="TOUSER";
  $returnMsg[1]=$splitMsg[1].", no valid bot command!";
  return $returnMsg;
 }

 $grpid=$channelInfoNew[$channelInfoKey]["chanid"];
 $fromChannel=$channelInfoNew[$channelInfoKey]["name"];
 if (strlen($fromChannel) >= 20) $fromChannel=substr($fromChannel,0,20)."...";
 
 logger("botcommand on [".$fromChannel."]: ".$askMessage);

 switch (strtolower($cmd)) {
  case "help":   
                 $sendMsg="<b> avaible commands</b>:<br>";
				 foreach ($globalsettings["bot"]["botcommands"] as $admincmd) $sendMsg.="-<code> ".$askcommand.$admincmd."</code><br>";
                 if ($channelInfoNew[$channelInfoKey]["mode"] == "ir") $sendMsg.="<br>-<code> ".$globalsettings["request"]["requestcommand"]."</code><br>";
				 $sendMsg.="<br>".$globalsettings["bot"]["version"]."<br>";
                 $returnMsg[0]="TOCHAN"; $returnMsg[1]=$sendMsg;
  break;
  case "search": $returnMsg=search($splitMsg, $askMessage, $grpid, $rerun);
  break;
  case "suche": $returnMsg=search($splitMsg, $askMessage, $grpid, $rerun);
  break;
  case "last5": $returnMsg=last($grpid,5,$channelInfoKey, $infoarray, $secarg);
  break;
  case "last10": $returnMsg=last($grpid,10,$channelInfoKey, $infoarray, $secarg);
  break;
  case "last20": $returnMsg=last($grpid,20,$channelInfoKey, $infoarray, $secarg);
  break;
  case "last30": $returnMsg=last($grpid,30,$channelInfoKey, $infoarray, $secarg);
  break;
  case "last50": $returnMsg=last($grpid,50,$channelInfoKey, $infoarray, $secarg);
  break;
  case "last100": $returnMsg=last($grpid,100,$channelInfoKey, $infoarray, $secarg);
  break;
  case "say": $returnMsg=askPaul();
  break;
  default: $returnMsg[0]="TOUSER"; $returnMsg[1]='no valid botcommand';
 } //switch end

return $returnMsg;
} // function end


function getAskTasks($data, $channelInfoKey) {
 global $globalsettings, $channelInfoNew; 

  $infoarray['mode']="generatebotmarker";
  $infoarray['channelid']=-1;
  $infoarray['channelname']=-1;
  $infoarray['msgid']=-1;
  $infoarray['msgdate']=-1;
  $infoarray['message']=-1;   
  $infoarray['userid']=-1;   
  $infoarray['username']=-1;
  $infoarray['topicid']=-1;
  $infoarray['replyid']=-1;   
  $infoarray['bot']=-1; 
  $infoarray['channelInfoKey']=$channelInfoKey;  

  // parse for video data
  if ($data!=false) if ($data != false) insertData(parseData($data), $channelInfoKey); 

  foreach($data['messages'] as $msg) {
   if (array_key_exists('message', $msg)) {
	$channelid=substr($data['chats'][0]['id'],4);
    $channelname=preg_replace("/[^a-zA-Z0-9]+!/u", "",$data['chats'][0]['title']);
    $msgid=$msg['id'];
    $msgdate=$msg['date'];
    $message=preg_replace("/[^a-zA-Z0-9]+!/u", "",$msg['message']);

    $userdata=getUserData($msg, $data);
    $userid=$userdata['user_id'];
    $username=$userdata['username'];	
	$botuser=$userdata['bot']; 
    
    $topic_id=-1;    
    if (array_key_exists("reply_to", $msg)) {
     if (array_key_exists("forum_topic", $msg["reply_to"])) {
      $topic_id=$msg["reply_to"]["reply_to_msg_id"]; 
      if (array_key_exists("reply_to_top_id",$msg["reply_to"])) $topic_id=$msg["reply_to"]["reply_to_top_id"]; 
     } // if (array_key_exists("forum_topic", $msg["reply_to"))
    } // if (array_key_exists("reply_to", $msg)) 

    $infoarray['channelid']=$channelid;
    $infoarray['channelname']=$channelname;
    $infoarray['msgid']=$msgid;
    $infoarray['msgdate']=$msgdate;
    $infoarray['message']=$message;   
    $infoarray['topicid']=$topic_id;
    $infoarray['userid']=$userid;   
    $infoarray['username']=$username;
	$infoarray['bot']=$botuser;   

    getMessageMarker($infoarray);
    forcedelete($infoarray);

	$askcommand="!".$channelInfoNew[$channelInfoKey]["channelbotname"]." ";
    if (strtolower(substr($msg['message'],0,strlen($askcommand))) == strtolower($askcommand)) {

	 $fromid=$userid;
	 $fromuser=$username;
	
	
	
      $grpid=substr($data['chats'][0]['id'],4);
      $grpname=preg_replace("/[^a-zA-Z0-9]+/", "",$data['chats'][0]['title']);
      $msgid=$msg['id'];
      $date=$msg['date'];
      $message=preg_replace("/[^a-zA-Z0-9]+!/", "",$msg['message']);
      // cleanup cacheAsks
      $sql="delete from cacheasks where grpid=".$grpid." and msgid < (select max(msgid)-150 as msgid from cacheAsks where grpid=".$grpid.")";
      pg_query($globalsettings["db"]["pg_conn"], $sql);

      $sql="select msgid from cacheAsks where grpid=".$grpid." and msgid=".$msgid;
      $result=pg_query($globalsettings["db"]["pg_conn"], $sql);
  
      while ($row = pg_fetch_array($result)) {
        $askid=$row['msgid'];
      } 
      if (!isset($askid)) { // no entry in db 
	  
	   getlastbotcommands($infoarray);
	   
	   
       $sql=sprintf("insert into cacheAsks values (%s,'%s',%s,%s,'%s',%s,'%s')\n", $grpid, pg_escape_string($globalsettings["db"]["pg_conn"], $grpname), $msgid, $fromid, pg_escape_string($globalsettings["db"]["pg_conn"], $fromuser), $date,pg_escape_string($globalsettings["db"]["pg_conn"], $message));
       pg_query($globalsettings["db"]["pg_conn"], $sql);
      
       $sql="insert into deletemessages (channelid, msgid, timestamp) values (".$infoarray['channelid'].",".$infoarray['msgid'].",".$infoarray['msgdate'].") on conflict do nothing;";
        pg_query($globalsettings["db"]["pg_conn"], $sql);
       
 
       $sendMsg=BotCommands($message, $grpid, $msgid, $infoarray);
       if ($sendMsg!=-1) { 
        sendMessage($sendMsg, $grpid, $msgid, $topic_id);
        if (array_key_exists('2', $sendMsg)) if ($sendMsg[2]=="SEARCHMAXRESULTS") sendMessage(BotCommands($message, $channelInfoKey, $msgid, $infoarray, $globalsettings["search"]["maxresults"]), $grpid, $msgid, $topic_id);
       } // if ($sendMsg!=-1) (when botcommands send hes own message
      } // if (!isset($askid))  // else echo "do nothing\n";
    }
  }
 }
}

function initbot($startup) {
 global $globalsettings, $channelInfoNew;
 logger("startup phase");
  
 $channelInfoNew=loadChannelConfig($startup);
 copyChannelConfig($channelInfoNew);

 $checkArray=array();
 foreach(array_keys($channelInfoNew) as $k) {
  switch ($channelInfoNew[$k]["mode"]) {
   case "ir": 	   
   case "i": 
   case "r":
           if ($channelInfoNew[$k]["from_topic_id"] != -1) { $fromprint=$channelInfoNew[$k]["chanid"].":".$channelInfoNew[$k]["from_topic_id"]; } else $fromprint=$channelInfoNew[$k]["chanid"];
           if ($channelInfoNew[$k]["status"] == "nook" ) { 
            logger("ERR: processing channel: ".$channelInfoNew[$k]["info"]." - ".$fromprint." (".$channelInfoNew[$k]['name'].")");
           } else {
            logger("processing channel: ".$fromprint." (".$channelInfoNew[$k]['name'].")");

            if (!asearch($channelInfoNew[$k]["peerid"], $checkArray)) { // do not read channel with from_topic_id twice or more
             $checkArray[]=$channelInfoNew[$k]["peerid"];
             $data=getLastMessages($k, "1", $startup);

             if ($data != false) insertData(parseData($data), $k);
            } // if (!asearch($channelInfo[$k]["peerid"], $checkArray) - do not read channel twice or more when from:topic is configured
           } // if ($channelInfoNew[$k]["status"] == "nook" )
   break;
   case "a":
           logger("processing: ".$k." (".$channelInfoNew[$k]['name'].")");
           $sendMsg="<b>pandabot startup</b> (loading channels...)"; 
           made("messages", "sendMessage", array("peer" => $globalsettings["bot"]["pandaownerid"], "message" => $sendMsg, "parse_mode" => "html"));
           adminCommands(getLastMessages($k, "1", $startup), $startup); 
   break;
   default:
  } // switch ($channelInfoNew[$k]["mode"]) 
 sleep(1);
 } // foreach(array_keys($channelInfoNew) as $k) 
  
  // function sendmessageintochannel($channelInfoKey, $message, $topicid, $html=true) {
 $date=date('m/d/Y H:i:s', time());
 made("messages", "sendMessage", array("peer" => $globalsettings["bot"]["pandaownerid"], "message" => "<b>done</b>: ".$date."<br> <br>use: <code>help</code>", "parse_mode" => "html")); // murmel
 logger("startup done"); 
} // function end


$startup=true; // first run detection

while (true) {
 if ($startup == true) {
  initbot($startup);
 } // if ($startup==true) {

 if ($startup!=true) {
  sleep(5);
  getLastMessages("-1", "-1", $startup);
  jobs(); 
 } // if ($startup!=true)
$startup=false;
} // while (true) 
