#!/usr/bin/perl
# Скрипт 
# http://userside.ua/wiki/index.php/Us_radio - информация о модуле
$zrevision = "3";
$zver = "us_radio v.1.2." . $zrevision; #версия
# ============================================================================= 
use DBI;
use Time::Local;
use FindBin;
use LWP::Simple;

$zpath = $FindBin::RealBin . '/';
require($zpath . 'us_config.tmp');

$ps_full_debug = 1;

$ps_timeout = 5;

$zmodule_param = 'M_RADIO';

if ($zusqlport eq "") {
    $zusqlport = 3306;
}

#Загружаем параметры
load_first_light();

#Загружаем настройки конфига
$ps_dbm_all_min = '';
$ps_dbm_all_max = '';
$ps_constr = "SELECT PARAM, VALUEINT, VALUESTR FROM tbl_conf";
printlog_sql_u($ps_constr);
    while (@ln = $rs->fetchrow_array()) {
        #Выясняем - нужно ли запускать модуль
        if ($ln[0] eq 'US_RADIO') {
            $ps_module_allow = $ln[1];
        }
        if ($ln[0] eq $zmodule_param) {
            $ps_needversion = $ln[2];
        }
    };
$rs->finish();

#Проверяем версию и включен ли модуль
version_verify_light();

#Начальные системные операции
load_second_light();

#Фиксируем в логе специфические параметры
printlog("ps_us_path         = " . $ps_us_path);
printlog("zcity_list         = " . $zcity_list);
printlog("ps_timeout         = " . $ps_timeout);

#Начинаем работать устройства

#Видимо не поддерживает
#109 - Ubiquiti Nanobridge M5 
                        
my @pmas_dev = ();
$pmas_dev_count = 0;
$ps_constr = qq{
    SELECT
        w.CODE
    FROM
        tbl_wifi AS w        
    INNER JOIN
        tbl_tovar AS t    
    ON
        w.SKLADCODE = t.CODE
    INNER JOIN
        tbl_tovartype AS tt
    ON
        tt.CODE = t.TOVARCODE
    WHERE
        tt.BASECODE NOT IN (109)
    AND
        (
            w.NAZV LIKE 'MIKROTIK%'
        OR
            w.NAZV LIKE 'UBNT%'
        OR
            w.NAZV LIKE 'UBIQUITI%'
        )
};
if ($zcity_list ne '') {
    $ps_constr .= qq{
    AND
        w.CITYCODE IN ($zcity_list)};
}
$ps_constr .= qq{
    ORDER BY 
        RAND()};
printlog_sql_u($ps_constr);
    while (@ln = $rs->fetchrow_array()) {
        if ($ps_full_debug eq 1) {
            printlog($pmas_dev_count . '| ID: ' . $ln[0]);
        }                
        $pmas_dev_count++;
        $pmas_dev[$pmas_dev_count][1] = $ln[0]; #s_CODE
    };
$rs->finish();

bufer_clear();

if ($pmas_dev_count < 1) {
    #Нет устройств вообще
    open ($ps_file101, ">>" . $ps_repalllog) || die;
        print $ps_file101 $zver . " Not enough device - exit\n";
        print $ps_file101 $zver . " Module FINISH at " . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
        print $ps_file101 "==============================================================\n";
    close $ps_file101;
    close $ps_file102;
    if ($zsilence ne 1) {
        print "Not enough device - exit\n";
        print "===================================\n";
    }
    $rs->finish();
    $conn1->disconnect();
    exit(1);
}

#Начинаем обходить устройства
printlog("Device work");
for ($pi_dev=1; $pi_dev<=$pmas_dev_count; $pi_dev++) {
    if ($ps_full_debug eq 1) {
        printlog('WORKING| ' . $pi_dev . ' ID: ' . $pmas_dev[$pi_dev][1]);
        #Сброс буферов
        bufer_clear();        
    }
    if ($ps_us_path ne '') {
        $ps_href = $ps_us_path . "/script/script_usradio.php?code=" . $pmas_dev[$pi_dev][1];
        
        my $ua = LWP::UserAgent->new(ssl_opts=>{verify_hostname => 0});
        $ua->timeout($ps_timeout);
        my $ps_content =  $ua->get($ps_href);
        if ($ps_content eq '') {
            $ps_content = 'timeout';
        }

        if ($ps_full_debug eq 1) {
            printlog('DEVICE: code=' . $pmas_dev[$pi_dev][1] . ' RESULT: ' . $ps_content);
        }             
        
    } else {
        printlog("Bad US path");
    }
}

#Сброс буферов
bufer_clear();

printlog("Module finish");
#Прописываемся в базу
$ps_constr = "UPDATE tbl_conf SET VALUEDATE = NOW() WHERE PARAM = '" . $zmodule_param . "'";
sql_do($ps_constr);
printlog("Request count: u:" . $zl_sqlc_u);
print $ps_file101 "===========================================\n";
print $ps_file101 "\n";
close $ps_file101;

open ($ps_file101, ">>" . $ps_repalllog) || die;
    print $ps_file101 $zver . " Module FINISH at " . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
    print $ps_file101 "==============================================================\n";
close $ps_file101;
close $ps_file102;
if ($zsilence ne 1) {
    print "finish module at " . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
    print "===================================\n";
}
$rs->finish();
$conn1->disconnect();
exit(0);

sub curlGet
{
    my $ua       = LWP::UserAgent->new(ssl_opts=>{verify_hostname => 0});
    my $url = URI->new($_[0]);
    $url->query_form($data);
    my $req = HTTP::Request->new(GET => $url);
    $req->header('content-type' => 'application/json', 'accept' => 'application/json');
    my $response = $ua->request($req);
    if ($isDebugMode eq 1) {
        print  Dumper($response);
    }
    return decode_json($response->decoded_content);
}

### ================================================================================================================
#Standart Module Light function v.1
#================================================================================================================
sub trim {
    my($string) = @_;
    for ($string) {
        s/^\s+//;
        s/\s+$//;
    }
    return $string;
}

#========================================================
sub formatdatetime {
    my $format = shift @_ || "YYYY-MM-DD hh:mm:ss";
    my $datetime = shift @_ || time;
    my %strings = (
        '500'=>"AM", '501'=>"PM",
        '400'=>"January", '401'=>"February", '402'=>"March", '403'=>"April", '404'=>"May", '405'=>"June", '406'=>"July", '407'=>"August", '408'=>"September", '409'=>"October", '410'=>"November", '411'=>"December",
        '300'=>"Jan", '301'=>"Feb", '302'=>"Mar", '303'=>"Apr", '304'=>"May", '305'=>"Jun", '306'=>"Jul", '307'=>"Aug", '308'=>"Sep", '309'=>"Oct", '310'=>"Nov", '311'=>"Dec",
        '200'=>"Sunday", '201'=>"Monday", '202'=>"Tuesday", '203'=>"Wednesday", '204'=>"Thursday", '205'=>"Friday", '206'=>"Saturday",
        '100'=>"Sun", '101'=>"Mon", '102'=>"Tue", '103'=>"Wed", '104'=>"Thu", '105'=>"Fri", '106'=>"Sat"
    );
    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($datetime);
    $year += 1900;
    if ($format=~m/AM/) {
        my $ampmhour=($hour % 12) || 12;
        $format=~s/hh/sprintf("%02u",$ampmhour)/eg;
        $format=~s/h/$ampmhour/eg;
        $format=~s/AM/($hour>11?"^501":"^500")/eg;
    } else {
        $format=~s/hh/sprintf("%02u",$hour)/eg;
        $format=~s/h/$hour/eg;
    };
    $format=~s/mm/sprintf("%02u",$min)/eg;
    $format=~s/m/$min/eg;
    $format=~s/ss/sprintf("%02u",$sec)/eg;
    $format=~s/s/$sec/eg;

    $format=~s/YYYY/$year/eg;
    $format=~s/YY/sprintf("%02u",$year % 100)/eg;
    $format=~s/MMMM/sprintf("^4%02u",$mon)/eg;
    $format=~s/MMM/sprintf("^3%02u",$mon)/eg;
    $format=~s/MM/sprintf("%02u",$mon+1)/eg;
    $format=~s/M/($mon+1)/eg;
    $format=~s/DDDD/sprintf("^2%02u",$wday)/eg;
    $format=~s/DDD/sprintf("^1%02u",$wday)/eg;
    $format=~s/DD/sprintf("%02u",$mday)/eg;
    $format=~s/D/$mday/eg;
    $format=~s/\^(\d\d\d)/$strings{$1}/g;
    return $format;
}

#========================================================
sub printlog{
    my($string) = @_;
    print $ps_file101 formatdatetime("DD.MM.YYYY hh:mm:ss", time) . " - " . $string . "\n";
    return $string;
}

#========================================================
sub sql_do{
    my($string) = @_;
    $zl_sqlc_u++;
    #print 'U: '.$zl_sqlc_u."\n";
    print $ps_file102 "U:" . $zl_sqlc_u . "| " . $string . ";\n";
    $conn1->do($string);
    return $string;
}

#========================================================
sub printlog_sql_u{
    my($string) =@_;
    $zl_sqlc_u++ ;
    print $ps_file102 "U:" . $zl_sqlc_u . '| ' . $string . ";\n";
    $rs = $conn1->prepare($string);
    $rs->execute();
    return $string;
}

#========================================================
sub load_first_light {
    $ps_repalllog = $ps_logpath . 'rep_alllog.txt';
    $ps_rep_logupd = $ps_logpath . 'rep_logupd.txt';
    $ps_rep_sql = $ps_logpath . 'rep_mysql.txt';

    if ($ARGV[0] eq 'debug' || $ARGV[1] eq 'debug' || $ARGV[2] eq 'debug') {
        $ps_full_debug = 1;
    }
        
    open ($ps_file101, ">>" . $ps_repalllog) || die;
        print $ps_file101 $zver . ' Module START at ' . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
    close $ps_file101;
    # Выведем заголовок типа данных
    if ($zsilence ne 1) {
        print $zver . "\n";
        print "===================================\n";
        print 'start module at ' . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
    }
    open ($ps_file101, ">" . $ps_rep_logupd) || die;
    print $ps_file101 "===========================================\n";
    printlog($zver." - start module");
    printlog($zpath);
    open ($ps_file102, ">" . $ps_rep_sql) || die;
    print $ps_file102 formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
    $zl_sqlc_u = 0;
    #Открываем базу
    $conn1 = DBI->connect("DBI:mysql:database=" . $zubase . ";host=" . $zuserver . ";port=" . $zusqlport, $zuuser, $zupass) || die $DBI::errstr;
    if ($zucp eq '') {
        $zucp = 'cp1251';
    }
    $conn1->do('set character set ' . $zucp);
    $conn1->do('set names ' . $zucp);
    return;
}

#========================================================
sub version_verify_light {
    if ($ps_module_allow ne 1) {
        open ($ps_file101, ">>" . $ps_repalllog) || die;
            print $ps_file101 $zver . " Module disabled in system - exit\n";
            print $ps_file101 $zver . " Module FINISH at " . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
            print $ps_file101 "==============================================================\n";
        close $ps_file101;
        close $ps_file102;
        if ($zsilence ne 1) {
            print "Module disabled in system - exit\n";
            print "=================================== \n";
        }
        $rs->finish();
        $conn1->disconnect();
        exit(1);
    }
    if (($zrevision < $ps_needversion) || ($ps_needversion < 1)) {
        open ($ps_file101, ">>" . $ps_repalllog) || die;
            print $ps_file101 $zver . ' Version failure. Need version: ' . $ps_needversion . " - exit\n";
            print $ps_file101 $zver . ' Module FINISH at ' . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
            print $ps_file101 "==============================================================\n";
        close $ps_file101;
        close $ps_file102;
        if ($zsilence ne 1) {
            print 'Version failure. Need version: ' . $ps_needversion . " - exit\n";
            print "===================================\n";
        }
        $rs->finish();
        $conn1->disconnect();
        exit(1);
    }
    return;
}

#========================================================
sub load_second_light {
    #Фиксируем время по базам
    $ps_constr = 'SELECT NOW()';
    printlog_sql_u($ps_constr);
    @ln = $rs->fetchrow_array();
    $ps_time_us = $ln[0];
    printlog('Time in DB UserSide: ' . $ps_time_us);

    #Прописываемся в базу
    $ps_info = $zver . '|' . $zpath . '|' . $ps_time_us . '|';
    $ps_constr = "UPDATE tbl_conf SET VALUEMEMO = '" . $ps_info . "' WHERE PARAM = '" . $zmodule_param . "'";
    sql_do($ps_constr);

    return;
}

#========================================================
sub bufer_clear{
    #Сброс буферов в файлы
    close $ps_file101;
    open ($ps_file101, ">>" . $ps_rep_logupd) || die;
    close $ps_file102;
    open ($ps_file102, ">>" . $ps_rep_sql) || die;
    return;
}

#========================================================