#!/usr/bin/perl

use strict;
use warnings "all";

use bytes;
use XML::Simple;

#use Data::Dumper;

use POSIX qw(strftime);
use Fcntl;

my $tmpdir = '/tmp';
my $citiesfile = "$tmpdir/cities.xml";
my $outfile = "$tmpdir/munin_weather.txt";

my $date = strftime "%Y-%m-%d", localtime;

sub parsedata($); # give $filename, returns [pressure, humidity, temperature, geomag index]
sub getIdByCountryAndCity(@);

# get yandex data with city<->id stuff
unless(-f $citiesfile){
	`curl -s -q -k --no-buffer --retry 3 --retry-delay 1 --connect-timeout 15 --tcp-nodelay 'https://pogoda.yandex.ru/static/cities.xml' >$citiesfile`;
	unless($? == 0){
		print "unable to download https://pogoda.yandex.ru/static/cities.xml";
		unlink($citiesfile);
		exit 1;
	}
}

my %city;
$city{'msk'} = getIdByCountryAndCity('Россия', 'Москва');
$city{'spb'} = getIdByCountryAndCity('Россия', 'Санкт-Петербург');
$city{'nsk'} = getIdByCountryAndCity('Россия', 'Новосибирск');
$city{'ksk'} = getIdByCountryAndCity('Россия', 'Красноярск');
$city{'nnov'} = getIdByCountryAndCity('Россия', 'Нижний Новгород');
$city{'vld'} = getIdByCountryAndCity('Россия', 'Владивосток');
$city{'vlg'} = getIdByCountryAndCity('Россия', 'Волгоград');
$city{'ast'} = getIdByCountryAndCity('Казахстан', 'Астана');

my $str = '';
foreach my $c (keys(%city)){
	my $id = $city{$c};
	my $xmldata = '';
	unless(-f "$tmpdir/$id.xml"){
		for(1..9){
			$xmldata .= `curl -s -k --no-buffer --connect-timeout 20 --tcp-nodelay https://export.yandex.ru/weather-ng/forecasts/$id.xml`;
			if($? == 0){
				sysopen(XMLDATA, "$tmpdir/$id.xml", O_WRONLY|O_CREAT|O_TRUNC)||die("Unable to write to $tmpdir/$id.xml");
				syswrite XMLDATA, $xmldata;
				close XMLDATA;
				last;
			}
			sleep 1;
		}
	}
	my @array = @{parsedata("$tmpdir/$id.xml")};
	$str .= sprintf( "%stemp:%s
%spres:%s
%shum:%s
%smag:%s
", $c, $array[2],
   $c, $array[0],
   $c, $array[1],
   $c, $array[3] );
}

sysopen(RESULT, $outfile, O_WRONLY|O_CREAT|O_TRUNC)||die("Unable to write to $outfile");
syswrite RESULT, $str;
close RESULT;

exit 0;

sub getIdByCountryAndCity(@){
        my ($country, $city) = @_;
        my $id = undef;
        my $simple = XML::Simple->new( KeyAttr => '' );
        my $ref = eval(sprintf("\$simple->XMLin('%s')", $citiesfile));
        foreach (@{$ref->{country}}){
                my %hash = %$_;
                my $a = sprintf("%s", $hash{'name'});
                next unless ($a eq $country);
                foreach(@{$hash{'city'}}){
                        next unless(${$_}{'content'} eq $city);
                        $id = ${$_}{'id'};
                        last;
                }
        }
        return $id;
}


sub parsedata($){
	my $file = shift ;
	my @a;
	my $simple = XML::Simple->new(KeyAttr => '');
# WTF?!!!
	my $data = eval(sprintf("\$simple->XMLin('%s')\n", $file));
# okay, parse stuff
	$a[0] = $data->{fact}->{pressure}->{content};
	$a[1] = $data->{fact}->{humidity};
	$a[2] = $data->{fact}->{temperature}->{content};
	foreach (@{$data->{day}}){
		my $ref = $_;
		if (defined($ref->{biomet}) and ($ref->{date} eq $date)){
			$a[3] = $ref->{biomet}{geomag};
			last;
		}
	}
	unless(defined($a[3])){
		my $newdate = strftime('%Y-%m-%d', localtime(time + 86400));
		foreach (@{$data->{day}}){
			my $ref = $_;
			if (defined($ref->{biomet}) and ($ref->{date} eq $newdate)){
				$a[3] = $ref->{biomet}{geomag};
				last;
			}
		}
	}
	unlink($file);
	return \@a;
}
