#!/usr/bin/perl

use Data::UUID;
use DBI;
use strict;

# Перевод текстовой БД КЛАДР в БД postgres
# Код: СС РРР ГГГ ППП АА
# СС – код субъекта Российской Федерации (региона)
# РРР – код района;
# ГГГ – код города;
# ППП – код населенного пункта
# АА – признак актуальности адресного объекта

# Справочник улиц:
# Код: СС РРР ГГГ ППП УУУУ АА
# СС – код субъекта Российской Федерации (региона)
# РРР – код района;
# ГГГ – код города;
# ППП – код населенного пункта
# УУУУ – код улицы;
# АА – признак актуальности наименования адресного объекта

# ID РФ - 1f2a59ff-e8c8-4cdb-8ff1-7ff5910e7d42

my $id_by_kod = {};
my @delayed;

open(SQL, '>./sql_kladr.sql');
print SQL "SET AUTOCOMMIT=off;\n";
print SQL "BEGIN;\n";
my $linecount = 0;
while (<STDIN>)
{
    my ($name, $socr, $kod) = split(/:/, $_);

    $name =~ s/^[ ]+//g;
    $name =~ s/[ ]+$//g;
    $socr =~ s/^[ ]+//g;
    $socr =~ s/[ ]+$//g;

    my $s = substr($kod, 0, 2);
    my $r = substr($kod, 2, 3);
    my $g = substr($kod, 5, 3);
    my $p = substr($kod, 8, 3);
    my $u = '';
    my $a = '';
    if (length($kod) == 13)
    {
	# Территория
	$a = substr($kod, 11, 2);
    }
    elsif (length($kod) == 17)
    {
	# Улица
	$u = substr($kod, 11, 4);
	$a = substr($kod, 15, 2);
    };

    if ($kod =~ /^[0-9]{2}0{11}$/)
    {
	# Субъект РФ
	my $ug = new Data::UUID;
	my $id = lc($ug->create_str());

	print SQL "INSERT INTO kladr (id, owner, intcode, name, socr) VALUES ('".$id."', '1f2a59ff-e8c8-4cdb-8ff1-7ff5910e7d42', '".$kod."', '".$name."', '".$socr."');\n";

	$id_by_kod->{$kod} = $id;
    }
    elsif ($kod =~ /^[0-9]{5}0{8}$/)
    {
	# Районы
	if ($r ne '000')
	{
	    my $owner = $s.'00000000000';

	    my $ug = new Data::UUID;
	    my $id = lc($ug->create_str());

	    if (!defined($id_by_kod->{$owner}) || ($id_by_kod->{$owner} eq ''))
	    {
		push(@delayed, { id => $id, kod => $kod, name => $name, socr => $socr, owner => '', ownerkod => $owner, });
	    }
	    else
	    {
		print SQL "INSERT INTO kladr (id, owner, intcode, name, socr) VALUES ('".$id."', '".$id_by_kod->{$owner}."', '".$kod."', '".$name."', '".$socr."');\n";
	    };

	    $id_by_kod->{$kod} = $id;
	};
    }
    elsif ($kod =~ /^[0-9]{8}0{5}$/)
    {
	# Города
	if ($g ne '000')
	{
	    my $owner = $s.$r.'00000000';

	    my $ug = new Data::UUID;
	    my $id = lc($ug->create_str());

	    if (!defined($id_by_kod->{$owner}) || ($id_by_kod->{$owner} eq ''))
	    {
		push(@delayed, { id => $id, kod => $kod, name => $name, socr => $socr, owner => '', ownerkod => $owner, });
	    }
	    else
	    {
		print SQL "INSERT INTO kladr (id, owner, intcode, name, socr) VALUES ('".$id."', '".$id_by_kod->{$owner}."', '".$kod."', '".$name."', '".$socr."');\n";
	    };

	    $id_by_kod->{$kod} = $id;
	};
    }
    elsif ($kod =~ /^[0-9]{11}0{2}$/)
    {
	# Населенные пункты
	if ($p ne '000')
	{
	    my $owner = $s.$r.$g.'00000';

	    my $ug = new Data::UUID;
	    my $id = lc($ug->create_str());

	    if (!defined($id_by_kod->{$owner}) || ($id_by_kod->{$owner} eq ''))
	    {
		push(@delayed, { id => $id, kod => $kod, name => $name, socr => $socr, owner => '', ownerkod => $owner, });
	    }
	    else
	    {
		print SQL "INSERT INTO kladr (id, owner, intcode, name, socr) VALUES ('".$id."', '".$id_by_kod->{$owner}."', '".$kod."', '".$name."', '".$socr."');\n";
	    };

	    $id_by_kod->{$kod} = $id;
	};
    }
    elsif ($kod =~ /^[0-9]{15}0{2}$/)
    {
	if (($u ne '000') && ($u ne ''))
	{
	    my $owner = $s.$r.$g.$p.'00';

	    my $ug = new Data::UUID;
	    my $id = lc($ug->create_str());

	    if (!defined($id_by_kod->{$owner}) || ($id_by_kod->{$owner} eq ''))
	    {
		push(@delayed, { id => $id, kod => $kod, name => $name, socr => $socr, owner => '', ownerkod => $owner, });
	    }
	    else
	    {
		print SQL "INSERT INTO kladr (id, owner, intcode, name, socr) VALUES ('".$id."', '".$id_by_kod->{$owner}."', '".$kod."', '".$name."', '".$socr."');\n";
	    };

	    $id_by_kod->{$kod} = $id;
	};
    };

    $linecount++;
    if ($linecount > 100)
    {
	print SQL "COMMIT;\n";
	print SQL "BEGIN;\n";
	$linecount = 0;
    };
};
print SQL "COMMIT;\n";

# Обрабатываем задержанные
if ($#delayed >= 0)
{
    $linecount = 0;
    print SQL "BEGIN;\n";
    foreach my $r (@delayed)
    {
	if (defined($id_by_kod->{$r->{ownerkod}}) && ($id_by_kod->{$r->{ownerkod}} ne ''))
	{
	    print SQL "INSERT INTO kladr (id, owner, intcode, name, socr) VALUES ('".$r->{id}."', '".$id_by_kod->{$r->{ownerkod}}."', '".$r->{kod}."', '".$r->{name}."', '".$r->{socr}."');\n";
	}
	else
	{
	    print "Не найден владелец с кодом ", $r->{ownerkod}, "\n";
	};

	$linecount++;
	if ($linecount > 100)
	{
	    print SQL "COMMIT;\n";
	    print SQL "BEGIN;\n";
	    $linecount = 0;
	};
    };
    print SQL "COMMIT;\n";
};

close(SQL);
