/**
 * This function provides synchronization of structure and data between two mysql servers. 
 * TODO: improve code sharing between the function and synchronization
 *
 * @param String $db - name of database, which should be synchronized
 * @param mixed $src_link - link of source server, note: if the server is current PMA server, use null
 * @param mixed $trg_link - link of target server, note: if the server is current PMA server, use null
 * @param boolean $data - if true, then data will be copied as well
 */
function PMA_replication_synchronize_db($db, $src_link, $trg_link, $data = true)
{
    $src_db = $trg_db = $db;
    $src_connection = PMA_DBI_select_db($src_db, $src_link);
    $trg_connection = PMA_DBI_select_db($trg_db, $trg_link);
    $src_tables = PMA_DBI_get_tables($src_db, $src_link);
    $source_tables_num = sizeof($src_tables);
    $trg_tables = PMA_DBI_get_tables($trg_db, $trg_link);
    $target_tables_num = sizeof($trg_tables);
    /**
     * initializing arrays to save table names 
     */
    $unmatched_num_src = 0;
    $source_tables_uncommon = array();
    $unmatched_num_trg = 0;
    $target_tables_uncommon = array();
    $matching_tables = array();
    $matching_tables_num = 0;
    /**
     * Criterion for matching tables is just their names.
     * Finding the uncommon tables for the source database
     * BY comparing the matching tables with all the tables in the source database
     */
    PMA_getMatchingTables($trg_tables, $src_tables, $matching_tables, $source_tables_uncommon);
    /**
     * Finding the uncommon tables for the target database
     * BY comparing the matching tables with all the tables in the target database
     */
    PMA_getNonMatchingTargetTables($trg_tables, $matching_tables, $target_tables_uncommon);
    /**
     * 
     * Comparing Data In the Matching Tables 
     * It is assumed that the matching tables are structurally 
     * and typely exactly the same  
     */
    $fields_num = array();
    $matching_tables_fields = array();
    $matching_tables_keys = array();
    $insert_array = array(array(array()));
    $update_array = array(array(array()));
    $delete_array = array();
    $row_count = array();
    $uncommon_tables_fields = array();
    $matching_tables_num = sizeof($matching_tables);
    for ($i = 0; $i < sizeof($matching_tables); $i++) {
        PMA_dataDiffInTables($src_db, $trg_db, $src_link, $trg_link, $matching_tables, $matching_tables_fields, $update_array, $insert_array, $delete_array, $fields_num, $i, $matching_tables_keys);
    }
    for ($j = 0; $j < sizeof($source_tables_uncommon); $j++) {
        PMA_dataDiffInUncommonTables($source_tables_uncommon, $src_db, $src_link, $j, $row_count);
    }
    /**
     * INTEGRATION OF STRUCTURE DIFFERENCE CODE
     *
     */
    $source_columns = array();
    $target_columns = array();
    $alter_str_array = array(array());
    $add_column_array = array(array());
    $uncommon_columns = array();
    $target_tables_keys = array();
    $source_indexes = array();
    $target_indexes = array();
    $add_indexes_array = array();
    $remove_indexes_array = array();
    $criteria = array('Field', 'Type', 'Null', 'Collation', 'Key', 'Default', 'Comment');
    for ($counter = 0; $counter < $matching_tables_num; $counter++) {
        PMA_structureDiffInTables($src_db, $trg_db, $src_link, $trg_link, $matching_tables, $source_columns, $target_columns, $alter_str_array, $add_column_array, $uncommon_columns, $criteria, $target_tables_keys, $counter);
        PMA_indexesDiffInTables($src_db, $trg_db, $src_link, $trg_link, $matching_tables, $source_indexes, $target_indexes, $add_indexes_array, $alter_indexes_array, $remove_indexes_array, $counter);
    }
    $matching_table_data_diff = array();
    $matching_table_structure_diff = array();
    $uncommon_table_structure_diff = array();
    $uncommon_table_data_diff = array();
    $uncommon_tables = $source_tables_uncommon;
    /**
     * Generating Create Table query for all the non-matching tables present in Source but not in Target and populating tables.  
     */
    for ($q = 0; $q < sizeof($source_tables_uncommon); $q++) {
        if (isset($uncommon_tables[$q])) {
            PMA_createTargetTables($src_db, $trg_db, $src_link, $trg_link, $source_tables_uncommon, $q, $uncommon_tables_fields, false);
        }
        if (isset($row_count[$q]) && $data) {
            PMA_populateTargetTables($src_db, $trg_db, $src_link, $trg_link, $source_tables_uncommon, $q, $uncommon_tables_fields, false);
        }
    }
}
 //contains the names of indexes that are excessive in target tables
 $alter_str_array = array(array());
 //contains the criteria for each column that needs to be altered in target tables
 $add_column_array = array(array());
 //contains the name of columns that need to be added in target tables
 /**
  * The criteria array contains all the criteria against which columns are compared for differences.
  */
 $criteria = array('Field', 'Type', 'Null', 'Collation', 'Key', 'Default', 'Comment');
 for ($i = 0; $i < sizeof($matching_tables); $i++) {
     /**
      * Finding out all the differences structure, data and index diff for all the matching tables only 
      */
     PMA_dataDiffInTables($src_db, $trg_db, $src_link, $trg_link, $matching_tables, $matching_tables_fields, $update_array, $insert_array, $delete_array, $fields_num, $i, $matching_tables_keys);
     PMA_structureDiffInTables($src_db, $trg_db, $src_link, $trg_link, $matching_tables, $source_columns, $target_columns, $alter_str_array, $add_column_array, $uncommon_columns, $criteria, $target_tables_keys, $i);
     PMA_indexesDiffInTables($src_db, $trg_db, $src_link, $trg_link, $matching_tables, $source_indexes, $target_indexes, $add_indexes_array, $alter_indexes_array, $remove_indexes_array, $i);
 }
 for ($j = 0; $j < sizeof($source_tables_uncommon); $j++) {
     /**
      * Finding out the number of rows to be added in tables that need to be added in target database
      */
     PMA_dataDiffInUncommonTables($source_tables_uncommon, $src_db, $src_link, $j, $row_count);
 }
 /**
  * Storing all arrays in session for use when page is reloaded for each button press 
  */
 $_SESSION['matching_tables'] = $matching_tables;
 $_SESSION['update_array'] = $update_array;
 $_SESSION['insert_array'] = $insert_array;
 $_SESSION['src_db'] = $src_db;
 $_SESSION['trg_db'] = $trg_db;