package network;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.net.ftp.*;
import other.ConnectionNotifier;

/**
 * DBModule Klasse
 * Stellt das DataAccessObject für die Kommunikation mit dem
 * FTP Server dar, handelt daher die Verbindung und führt den gesamten
 * Datentransfer durch
 */
public class FTPModule {
	
	// Attribute
	private FTPClient ftpClient = null;
	private boolean bIsConnected = false;
	
	private String sUser;
	private String sPassword;
	private String sDirectory;
	
    private ConnectionNotifier networkHandler;
	
    /**
     * Konstruktor
     * @param netH NetworkHandler Objekt zur Statusmeldung
     */
	public FTPModule(ConnectionNotifier netH){
		networkHandler = netH;
		ftpClient = new FTPClient();
	}

	/* ##########################################################################
	 * 						CONNECTION METHODEN
	 * ##########################################################################*/		

 	/**
 	 * Stellt eine Verbindung mit dem gewünschten Server her
 	 * @return true bei Erfolg, sost false
 	 */
 	public boolean connect(String ip) {
 		// Sicherheitsabfrage
 		if(bIsConnected){
			System.out.println("Fehler FTPModule.connect(): bereits verbunden");
 			return false;
 		}
 		try{
 			ftpClient.connect(ip, 21);
 			if(!ftpClient.login(sUser,sPassword)) return false;
 			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
 		}catch (Exception ex){
 			// Debug
 			System.out.println("Verbindung zu FTP Server konnte nicht hergestellt werden!");
 			return false;
 		}
		changeWorkDir(sDirectory);
 		
 		bIsConnected=true;
 		networkHandler.connectionNotification();
 		return true;
 	}
 	
    /**
     * Liefert zurück, ob man gerade verbunden ist
     * @return true wenn verbunden, sonst false
     */
    public boolean isConnected(){
    	return bIsConnected;
    }
 	
    /**
     * Überprüft die Verbindung
     */
    public void checkConnection(){
    	try{
    		ftpClient.list();
    	}
    	catch(Exception e){
    	 	disconnect();	
    	} 
    }
    
    /**
     * Trennt die FTP-Verbindung
     */
    public void disconnect(){
    	bIsConnected=false;
 		try{
 			ftpClient.disconnect();
 		}catch (Exception ex){
 		}
 		networkHandler.connectionNotification();
    }
 
	/* ##########################################################################
	 * 						ÖFFENTLICHE METHODEN
	 * ##########################################################################*/	    

	/**
	 * Legt die Daten für das Einloggen fest
	 * @param user Benutzername für die Anmeldung am MySQL Server
	 * @param passw Passwort für die Anmeldung am MySQL Server
	 * @param dir Verzeichnis, das die Daten am FTP Server enthält
	 */
	public void setLoginData(String user, String passw, String dir){
		sUser = user;
		sPassword = passw;
		sDirectory = dir;
	}
	
	/**
	 * Lädt eine Datei auf den Server hinauf und löscht im 
	 * Anschluss die lokale Kopie
	 * @param sFile Name der Datei die upgeloadet werden soll
	 * @return true wenn es funktioniert hat, sonst false
	 */
	public boolean uploadFile(String sFile){
		try{
			//InputStream erzeugen
			FileInputStream in = new FileInputStream(sFile);
			//Dateiname holen
			File fFile = new File(sFile);
			ftpClient.storeFile(fFile.getName(),in);
			if (in!=null) in.close();
		}catch(Exception e){
        	disconnect();
			return false;
		}
		return true;	
	}
	
	/**
	 * Lädt die gewünschte Datei vom Server über die geöffnete
	 * FTP Verbindung herunter
	 * @param sFile das File, das vom Server heruntergeladen werden soll
	 * @param localDir das lokale Verzeichis in dem die neue Datei gespeichert werden soll
	 * @return true wenn es funktioniert hat, sonst false
	 */
	public boolean receiveFile(String sFile, String sLocalDir) {
		try{
			//OutputStream erzeugen u. File herunterladen
			FileOutputStream out = new FileOutputStream(sLocalDir + sFile);
			ftpClient.retrieveFile(sFile, out);
			if (out != null)
				out.close();
		}catch(Exception ex){
        	disconnect();
			return false;
		}
		return true;
 	}

	/**
	 * Ändert das aktuelle Arbeitsverzeichnis auf dem FTP Server
	 * @param sWorkDir das Verzeichnis in das gewechselt werden soll
	 * @return true wenn es funktioniert, sonst false
	 */
 	public boolean changeWorkDir(String sWorkDir) {
 		try{
 			ftpClient.changeWorkingDirectory(sWorkDir);
 		}catch (Exception ex) {
        	disconnect();
 			return false;
 		}
 		return true;
 	}    
    
 	/**
 	 * Liefert eine Auflistung der Dateien im Verzeichnis
 	 * @return ein String-Array mit den Dateinamen
 	 */
 	public String[] listFiles(){
 		try{
 			return ftpClient.listNames();
 		}catch(Exception e){
 			return new String[]{ };
 		}
 	}
 	
 	/**
 	 * Entfernt die angegebene Datei vom Server und aus dem
 	 * lokalen Fake-Verzeichnis
 	 * @param sName Name der Datei
 	 * @return true bei Erfolg, sonst false
 	 */
 	public boolean deleteFile(String sName){
 		try{	
 			ftpClient.deleteFile(sName);	
 		}catch(IOException e){
        	disconnect();
 			return false;
 		}
 		return true;
 	}
 
}
