<?php
set_error_handler ('php_error_handler');
error_reporting (E_ALL | E_STRICT); ini_set ('display_errors', 1);
date_default_timezone_set ('Europe/Moscow');

ini_set ('memory_limit', '2048M'); gc_enable();
ini_set ('max_execution_time', 0);

/* * */

$correct_files_path = 'D:/Backup';
$local_files_path = strtr (dirname (dirname (dirname (__FILE__))), '\\', '/'); 

$book_maker = rglob ($correct_files_path, 'os2book-v*.cmd');

if (count ($book_maker) == 1) {
    $processed = process_files_step_1 ($local_files_path, strtr (dirname ($book_maker[0]), '\\', '/')); print "\n";
    $processed = process_files_step_2 ($local_files_path, strtr (dirname ($book_maker[0]), '\\', '/'), $processed);
} else {
    print 'File not found: "os2book-v*.cmd" (or too many files)'."\n"; throw new Exception ();
}

exit;

function process_files_step_1 ($local_files_path, $path_to_book_maker) {
    $processed = array (
                         'correct' => array (),
                         'local.kv' => array ()
                       );

    $files = rglob ($path_to_book_maker, '*');

    foreach ($files as $file_name) {
        $local_file_name = strtr (strreplace ($file_name, $path_to_book_maker, ''), '\\', '/');
        $local_file_full_name = strtr ($local_files_path.$local_file_name, '\\', '/');

        if (file_exists ($local_file_full_name)) {
            touch ($local_file_full_name, filemtime ($file_name)); 
            print $local_file_full_name.' <- '.$file_name."\n";

            $processed['local.kv'][$local_file_name] = '*';
        }

        $processed['correct'][] = $local_file_name;
    }

    return $processed;
}

function process_files_step_2 ($local_files_path, $path_to_book_maker, $processed_step_1) {
    $processed = array (
                         'correct' => $processed_step_1['correct'],
                         'local'   => array ()
                       );

    $files = rglob ($local_files_path, '*');

    foreach ($files as $file_name) {
        $local_file_name = strtr (strreplace ($file_name, $local_files_path, ''), '\\', '/');
        $local_file_full_name = strtr ($file_name, '\\', '/');

        if (!isset ($processed_step_1['local.kv'][$local_file_name])) {
            $correct_file_name = find_similar ($local_file_name, $processed['correct']); 
            $correct_file_full_name = strtr ($path_to_book_maker.$correct_file_name, '\\', '/');

            touch ($local_file_full_name, filemtime ($correct_file_full_name)); 
            print $local_file_full_name.' <- '.$correct_file_full_name."\n";

            $processed['local'][] = $local_file_name;
        }
    }

    return $processed;
}

function find_similar ($file_name, $names) {
    $min_distance = 0; $similar_name = '';

    foreach ($names as $name) {
        $distance = levenshtein ($file_name, $name);

        if ($distance > 0) {
            if ($min_distance == 0) {
                $min_distance = $distance; $similar_name = $name;
            } else {
                if ($distance < $min_distance) {
                    $min_distance = $distance; $similar_name = $name;
                } else {
                    ;
                }
            }
        } else {
            $similar_name = $name; break;
        }
    }

    return $similar_name;
}

/* * */

function rglob ($path_w_slash, $pattern, $flags = 0) {
    if (substr ($path_w_slash, -1) != '/') $path_w_slash .= '/';

    $paths = glob ($path_w_slash.'*', GLOB_ONLYDIR);
    $files = glob ($path_w_slash.$pattern, $flags);

    foreach ($paths as $next_step_path) {
        $next_step_files = rglob ($next_step_path.'/', $pattern, $flags); 
        foreach ($next_step_files as $next_step_file) { $files[] = $next_step_file; }
    }

    return $files;
}

/* * */

function strreplace ($haystack, $needle, $str) { return str_replace ($needle, $str, $haystack); }
function yield_time () { if (function_exists ('proc_nice')) { proc_nice (abs (31)); } else { usleep (25); } }

function php_error_handler ($errno, $errstr, $errfile, $errline, $vars = null) { 
    die ("\n\n".'['.$errno.'] '.$errstr.' ('.strtr ($errfile, '\\', '/').', '.$errline.')'."\n\n");
}
