#!/usr/bin/perl 

#
# Copyright (C) Roman Dmitriev, rnd@rajven.ru
#

use utf8;
use warnings;
use Encode;
use open qw(:std :encoding(UTF-8));
no warnings 'utf8';

use English;
use FindBin '$Bin';
use lib "/opt/Eye/scripts";
use Data::Dumper;
use eyelib::config;
use eyelib::main;
use eyelib::logconfig;
use eyelib::database;
use eyelib::common;
use eyelib::net_utils;
use strict;
use warnings;

binmode(STDOUT, ':encoding(utf8)');
binmode(STDERR, ':encoding(utf8)');

my $clean_run = $ARGV[0] || '';
my $batch_size = 1000;

# Очищаем таблицу если нужно
if ($clean_run eq 'clean') {
    do_sql($dbh, "TRUNCATE TABLE mac_vendors");
    print "Таблица очищена\n";
}

# Получаем существующие OUI из базы
my %existing_oui;
if ($clean_run ne 'clean') {
    print "Получаем существующие OUI из базы...\n";
    my $sth = $dbh->prepare("SELECT oui FROM mac_vendors");
    $sth->execute;
    while (my ($oui) = $sth->fetchrow_array) {
        $existing_oui{$oui} = 1;
    }
    $sth->finish;
    print "Найдено существующих записей: " . scalar(keys %existing_oui) . "\n";
}

my $filename = "/opt/Eye/scripts/utils/mac-oids/manuf.csv";
open(my $fh, '<:encoding(utf8)', $filename) 
    or die "Не удалось открыть файл $filename: $!";

print "Обработка файла...\n";

my @batch_data;
my $total_processed = 0;
my $total_inserted = 0;
my $line_num = 0;

while (my $line = <$fh>) {
    $line_num++;
    chomp $line;
    
    # Пропускаем пустые строки
    next if $line =~ /^\s*$/;
    
    # Пропускаем заголовок
    next if $line_num == 1 && $line =~ /^MAC Prefix/;
    
    # Разбиваем на поля
    my @fields = split(/;/, $line, 3);
    
    my $oui = $fields[0] || '';
    my $company = $fields[1] || '';
    my $address = $fields[2] || '';
    
    # Убираем кавычки если есть
    $oui =~ s/^\"|\"$//g;
    $company =~ s/^\"|\"$//g;
    $address =~ s/^\"|\"$//g;
    
    # Очищаем данные
    $oui = trim($oui);
    $company = trim($company);
    $address = trim($address);
    
    # Пропускаем если нет OUI
    next unless $oui && $oui =~ /\S/;
    
    # Убираем маску подсети
    $oui =~ s{/[0-9]+}{};
    
    # Нормализуем MAC
    $oui = mac_splitted($oui);
    
    # Проверяем минимальную длину
    next unless length($oui) >= 8;
    
    # Пропускаем если уже есть в базе
    next if $existing_oui{$oui};
    
    # Добавляем в пакет
    push @batch_data, [$oui, $company, $address];
    $total_processed++;
    
    # Вставляем пакет при достижении размера
    if (@batch_data >= $batch_size) {
        $total_inserted += insert_batch_simple(\@batch_data);
        @batch_data = ();
    }
    
    # Прогресс
    print "Обработано строк: $line_num\r" if ($line_num % 1000 == 0);
}

close $fh;

# Вставляем остатки
if (@batch_data) {
    $total_inserted += insert_batch_simple(\@batch_data);
}

print "\n\nИтоги:\n";
print "Обработано строк: $total_processed\n";
print "Добавлено записей: $total_inserted\n";
print "Done!\n";

exit;

# Простая пакетная вставка
sub insert_batch_simple {
    my ($batch_ref) = @_;
    my @data = @$batch_ref;
    
    return 0 unless @data;
    
    my $sth = $dbh->prepare("
        INSERT INTO mac_vendors (oui, companyname, companyaddress) 
        VALUES (?, ?, ?)
    ");
    
    $dbh->begin_work;
    my $inserted = 0;
    
    foreach my $row (@data) {
        my ($oui, $company, $address) = @$row;
        
        eval {
            $sth->execute($oui, $company, $address);
            $inserted++;
        };
        
        if ($@) {
            warn "Ошибка при вставке $oui: $@\n";
        }
    }
    
    $dbh->commit;
    $sth->finish;
    
    return $inserted;
}
