/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hu.nir.nmail.migration;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JProgressBar;

/**
 *
 * @author attila
 */
public class MigrationManager implements Runnable {
    private DatabaseManager oldDB;
    private DatabaseManager newDB;
    private Thread migrationThread;
    private JProgressBar mainProgress; 
    private JProgressBar addressProgressBar;
    
    public MigrationManager(DatabaseManager oldDB, DatabaseManager newDB) {
        this.oldDB = oldDB;
        this.newDB = newDB;
    }
    
    public void migrate(JProgressBar mainProgress, JProgressBar addressProgressBar) {
        migrationThread = new Thread(this);
        this.mainProgress = mainProgress;
        this.addressProgressBar = addressProgressBar;
        migrationThread.start();
    }
    
    private void sleep() {
        try {
            Thread.sleep(300);
        } catch (InterruptedException ex) {
            Logger.getLogger(MigrationManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void run() {
        Savepoint oldsave = null;
        Savepoint newsave = null;
        try {
            oldsave = oldDB.creatTransaction("oldDB");
            newsave = newDB.creatTransaction("newDB");
            ResultSet mailUserCountResult = oldDB.executeSelect("SELECT count(*) as c from mailuser");
            mailUserCountResult.next();
            int mc = mailUserCountResult.getInt("c");
            if (mainProgress != null) {
                mainProgress.setMinimum(0);
                mainProgress.setMaximum(mc);
                mainProgress.setValue(0);
            }
            Date now = new Date();
            SimpleDateFormat df = new SimpleDateFormat();
            df.applyPattern("yyy-MM-dd");
            String nowS = df.format(now);
            ResultSet mailUserResult = oldDB.executeSelect("SELECT * from mailuser");
            if (mailUserResult != null) {
                while(mailUserResult.next()) {
                    String user_name = mailUserResult.getString("loginname");
                    String password = mailUserResult.getString("password");
                    
                    newDB.executeInsert("INSERT INTO nmail_user_login (user_name, password, from_date) values ('"+user_name+"',md5('"+password+"'),'"+nowS+"')");
                    ResultSet rs = newDB.executeSelect("SELECT id FROM nmail_user_login WHERE user_name = '"+user_name+"' AND password = md5('"+password+"')");
                    rs.next();
                    long id = rs.getLong("id");
                    rs.close();
                    newDB.executeInsert("INSERT INTO nmail_user (user_id) values("+id+")");
                    String pop3host = mailUserResult.getString("pop3host");
                    String pop3account = mailUserResult.getString("pop3account");
                    String pop3password = mailUserResult.getString("pop3pw");
                    int port = mailUserResult.getInt("port");
                    boolean ssl = mailUserResult.getBoolean("ssl");
                    newDB.executeInsert("INSERT INTO mail_folder (user_id, pop3_host, pop3_password, pop3_user_name, port, ssl) values("+id+",'"+pop3host+"','"+pop3password+"','"+pop3account+"',"+port+","+ssl+")");
                    boolean abletosetsendername = mailUserResult.getBoolean("abletosetsendername");
                    boolean abletosetsenderaddress = mailUserResult.getBoolean("abletosetsenderaddress");
                    boolean abletosetsender = false;
                    if (abletosetsenderaddress && abletosetsendername) {
                        abletosetsender = true;
                    }
                    boolean canImport = mailUserResult.getBoolean("canimport");
                    boolean canSetPop3 = mailUserResult.getBoolean("abletosetpop");
                    newDB.executeInsert("INSERT INTO user_restriction (user_id, able_to_set_sender,can_import, can_set_pop3) values ("+id+","+abletosetsender+","+canImport+","+canSetPop3+")");
                    String bounceaddress = mailUserResult.getString("bounceaddress");
                    if (bounceaddress != null && !bounceaddress.equals("null")){
                        bounceaddress = "'"+bounceaddress+"'";
                    }
                    boolean bouncedDelivered = mailUserResult.getBoolean("bounceddelivered");
                    int timelimit = mailUserResult.getInt("timelimit");
                    int messagelimit = mailUserResult.getInt("messagelimit");
                    String defaultsendername = mailUserResult.getString("defaultsendername");
                    if (defaultsendername != null && !defaultsendername.equals("null")){
                        defaultsendername = "'"+defaultsendername+"'";
                    }
                    String defaultsenderaddress = mailUserResult.getString("defaultsenderaddress");
                    if (defaultsenderaddress != null && !defaultsenderaddress.equals("null")){
                        defaultsenderaddress = "'"+defaultsenderaddress+"'";
                    }
                    newDB.executeInsert("INSERT INTO user_setting (user_id, bounce_address,bounced_delivered,default_sender_address,default_sender_name,message_limit, time_limit) values ("+id+","+bounceaddress+","+bouncedDelivered+","+defaultsenderaddress+","+defaultsendername+","+messagelimit+","+timelimit+")");
                    
                    ResultSet addressResult = oldDB.executeSelect("SELECT * FROM address WHERE loginname = '"+user_name+"'");
                    ResultSet addressCountResult = oldDB.executeSelect("SELECT count(*) as c FROM address WHERE loginname = '"+user_name+"'");
                    addressCountResult.next();
                    int ac = addressCountResult.getInt("c");
                    if (addressResult != null) {
                        if (addressProgressBar != null) {
                            addressProgressBar.setMinimum(0);
                            addressProgressBar.setMaximum(ac);
                            addressProgressBar.setValue(0);
                        }
                        sleep();
                        while (addressResult.next()) {
                            String email = addressResult.getString("address");
                            newDB.executeInsert("INSERT INTO email_address (email_address,user_id) values ('"+email+"',"+id+")");
                            if (addressProgressBar != null) {
                                addressProgressBar.setValue(addressProgressBar.getValue()+1);
                            }
                            sleep();
                        }
                        if (addressProgressBar != null) {
                            addressProgressBar.setValue(0);
                        }
                    }
                    if (mainProgress != null) {
                        mainProgress.setValue(mainProgress.getValue()+1);
                    }
                    sleep();
                }
            }
            if (mainProgress != null) {
                mainProgress.setValue(0);
            }
            newDB.commit();
        } catch (Exception ex) {
            try {
                Logger.getLogger(MigrationManager.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
                if (oldsave != null)
                    oldDB.rollback(oldsave);
                if (newsave != null)
                    newDB.rollback(newsave);
            } catch (SQLException ex1) {
                Logger.getLogger(MigrationManager.class.getName()).log(Level.SEVERE, ex1.getLocalizedMessage(),ex1);
            }
        } finally {
            if (newDB != null)
                newDB.connectionClose();
            if (oldDB != null)
                oldDB.connectionClose();
        }
    }
}
