<?php

/*
 * NOTES FROM: https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/introduction
 * FOR Essential access we have:
 1) Five rules per stream
 2) 25 requests per 15 minutes when using the POST /2/tweets/search/stream/rules endpoint to add rules
 3) 50 Tweets/second delivery cap for connections
 4) Can only use the core operators when building your rule
 5) Can build rules up to 512 characters in length
 5) Cannot use the recovery and redundancy features
 */

namespace Felix\TwitterStream;

require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/twitterCredentials.php';
require_once __DIR__ . '/../../parseUtils.php'; //also includes demosettings


function filter_app_core_db_v2($tweeterBK){
    $tweeterBK = constant($tweeterBK);
    $mysqli = sqlCreateConnection("Twitter v2 - filter_app_core_db_v2");
    while (true) {
        $start_time = time();
        printf("\nfilter_app_core_db_v2\n");
        try {
            sqlQuery($mysqli, "UPDATE crawler_settings SET isRunning=1,error='' WHERE prop='crawler'");
            streaming_v2($tweeterBK);
        } catch (Exception $e) {
            $error_msg = "Stream unexpectedly broke with message: " . $e->getMessage();
            sqlQuery($mysqli, "UPDATE crawler_settings SET isRunning=0,error='$error_msg' WHERE prop='crawler'");
            echo $error_msg;
            write_to_log("ERROR", $error_msg);
            
        }
    }
}



function streaming_v2($tweeterBK){
    write_to_log("INFO", "streaming_v2");
    
    $connection = new \Felix\TwitterStream\TwitterConnection($tweeterBK # the one you got from the Developer Portal
        );
    
    $stream = new \Felix\TwitterStream\Streams\FilteredStream();
    
    
    
    $stream->fields([
        'tweet' => ["attachments","author_id","context_annotations","conversation_id","created_at","edit_controls","entities","geo","id","in_reply_to_user_id","lang","public_metrics","possibly_sensitive","referenced_tweets","reply_settings","source","text","withheld"],
        'user' => ["created_at","description","entities","id","location","name","pinned_tweet_id","profile_image_url","protected","public_metrics","url","username","verified","verified_type","withheld"]
    ])
    ->expansions('referenced_tweets.id,author_id')
    ->listen($connection, function (object $tweet) {
        //gets tag=>project/projects
        $crawler_tags_arr = getCrawlerTagsFromFile();//getSystemSettingsProp($mysqli, "crawler_tag");
        
        //check if the tag matches
        if(property_exists($tweet, 'matching_rules')){
            $matching_rules_arr = $tweet->matching_rules; //gets the matching rules from the tweet
            write_to_log("INFO", "Matching rules ". json_encode($matching_rules_arr,true));
            
            //iterate over each matching_rule
            foreach($matching_rules_arr as $matchRule){
                write_to_log("INFO", "$matchRule->tag ". json_encode($crawler_tags_arr,true));
                
                if(array_key_exists($matchRule->tag, $crawler_tags_arr)){
                    $crawler_db = $crawler_tags_arr[$matchRule->tag];
                    $mysqli = sqlCreateDBConnection(null);
                    $response = sqlQuery($mysqli, "SHOW DATABASES LIKE '$crawler_db'");
                    if ($response->num_rows == 0) {
                        write_to_log("INFO", "no db with this name in the server");
                        //  sqlClose($mysqli, "twitter v2");
                        continue;//no db with this name in the server
                    }
                    // sqlClose($mysqli, "twitter v2");
                    write_to_log("INFO", "Insert to $crawler_db - for tag $matchRule->tag");
                    $mysqlic = sqlCreateDBConnection($crawler_db);
                    $text = json_encode($tweet, JSON_UNESCAPED_UNICODE);
                    $text = $mysqlic->real_escape_string($text);
                    $id = intval($tweet->data->id);
                    $query = "INSERT into raw_stream_data(element_id, source, data) VALUES($id, 1, '$text')  ON DUPLICATE KEY UPDATE id=id"; //source is 1 for twitter
                    sqlQueryUnique($mysqlic, $query,"Duplicate"); //will insert and prevent looping with this extra flag - the error of duplicated
                    //sqlClose($mysqlic, "streaming_v2");
                }
                
            }
        }
    });
}

/**
 * get crawler tags - will use it to assign by tag to projects
 * @return mixed
 */
function getCrawlerTagsFromFile(){
    global $localProjectsFolder;
    $ret = [];
    
    $filename = $localProjectsFolder . DIRECTORY_SEPARATOR . 'crawlerTags.json';
    write_to_log("INFO", "No file in $filename");
    
    if(file_exists($filename)){
        $ret = json_decode(file_get_contents($filename,true), true);
    }
    else{
        write_to_log("INFO", "No file in $filename");
    }
    return $ret;
    
}
/**
 *
 * @param unknown $matching_rules_arr
 * @param unknown $crawler_tag
 * @return boolean
 */
function validateMatchingRules($matching_rules_arr, $crawler_tag){
    foreach($matching_rules_arr as $matchRule){
        write_to_log("ERROR", json_encode($matchRule,true));
        if($crawler_tag == $matchRule->tag){
            write_to_log("INFO", "twitter v2 tag match tags $crawler_tag and $matchRule->tag");
            
            return true;
        }
    }
    write_to_log("INFO", "No Tag Matches for $crawler_tag");
    
    return false;
}

/**
 *
 */
function validateTagCrawler($mysqli, $crawler_tag, $tag){
    if(empty($crawler_tag) || $crawler_tag == "-" || $tag == 'crawler_tag'){
        return true;
    }
    return false;
}

/**
 * get current rules per the user
 * @return array
 */
function getTwitterRules($tweeterBK){
    $crawler_tags_arr = getCrawlerTagsFromFile();
    if(empty($crawler_tags_arr)){
        return ["error" => "no tags file configured"];
    }
    $tweeterBK = constant($tweeterBK);
    $connection = new \Felix\TwitterStream\TwitterConnection($tweeterBK);
    
    $rule = new RuleManager($connection);
    return $rule->all();
    
}

function deleteTwitterRule($id, $tweeterBK){
    $tweeterBK = constant($tweeterBK);
    $connection = new \Felix\TwitterStream\TwitterConnection($tweeterBK);
    $rule = new RuleManager($connection);
    $rule->delete($id);
    return true;
    
}

function saveTwitterRule($input, $tweeterBK){
    $tweeterBK = constant($tweeterBK);
    $data = json_decode($input,true);
    $rule_str = $data['rule'];
    $tag = $data['tag'];
    
    $connection = new \Felix\TwitterStream\TwitterConnection($tweeterBK);
    $rule = new RuleManager($connection);
    if(!$rule->validate($rule_str)){
        write_to_log("ERROR", "Rule issue");
        return ["error"=>"Rule issue"];
    }
    $rule->save($rule_str, $tag);
    return true;
}



