package vut.msa.test;

import java.io.*;
import java.net.*;
import java.security.Security;
import java.util.ArrayList;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.apache.log4j.Logger;
import vut.msa.monitor.system.SystemInformation;
import vut.msa.security.SSLContextFactory;
import vut.msa.transport.FileStreamer;
import vut.msa.utilities.DocumentFileFilter;
import vut.msa.utilities.ZipUtilities;

public class TestClient {

    private static final Logger log = Logger.getLogger(TestClient.class);
    private SSLContext sslContext;
    private FileStreamer streamer;

    public TestClient() throws Exception {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

        SSLSocket socket = null;

        PrintWriter out = null;
        BufferedReader in = null;

        try {
            sslContext = SSLContextFactory.getDefault();

        } catch (IOException ex) {
            System.err.println("Could not listen on port.");
            System.exit(-1);
        }

        try {

            SSLSocketFactory factory = sslContext.getSocketFactory();

            //LAN, 802.11g a WAN/VPN
            //socket = (SSLSocket) factory.createSocket("10.0.5.118", 9999);

            //Internet
            //socket = (SSLSocket) factory.createSocket("212.55.244.22", 9999);

            //Localhost
            socket = (SSLSocket) factory.createSocket("localhost", 9999);

            SSLSession sslSession = socket.getSession();
            log.info("Session info: " + sslSession.getCipherSuite());
            log.info("Communication port: " + socket.getPort());
            streamer = new FileStreamer(socket);

            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        } catch (UnknownHostException e) {
            e.printStackTrace();
            System.err.println("Don't know about host: localhost");
            System.exit(1);
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("Couldn't get I/O for the connection to: taranis.");
            System.exit(1);
        }

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
        String fromServer;

        SystemInformation info = new SystemInformation();

        try {
            System.out.println ("System uptime: " + info.getFormatedUptime((int)info.getUptime()));
            System.out.println ("Pocet dokumentov: " + info.getDocumentsDir().getFiles());
            System.out.println ("Velkost adresara: " + info.getDocumentsDir().getDiskUsage()/(1024*1024) + " MB");
            System.out.println ("System free memory: " + info.getMemoryInfo().getUsedPercent());

            System.out.println ("Disk C total : " + info.getFileSystemInfo().getFileSystemUsage("D:\\").getTotal());
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }

        while ((fromServer = in.readLine()) != null) {
            log.info("Server task: " + fromServer);

            if (fromServer.equals("IDENTIFY")) {
                out.println("KOSICE1|testPassword");
            }

            if (fromServer.equals("UNAUTHORIZED")) {
                log.error("Unathorized to server.");
                out.write("CLOSE");
                break;
            }

            if (fromServer.equals("TAKE_ACTION")) {
                out.println("WRITE");
                //out.println("INFO");
                //out.println("READ");
                continue;
            }
            /*
            fromUser = stdIn.readLine();
            if (fromUser != null) {
                System.out.println("Client: " + fromUser);
                out.println(fromUser);
            }
             *
             */

            if (fromServer.equals("SEND_DATA")) {
                long start = System.currentTimeMillis();

                String directory = "E:\\E-Books\\Project Management";
                ArrayList<String> files = new ArrayList<String>();
                File[] content = new File(directory).listFiles(new DocumentFileFilter());
                for (File file : content) {
                    log.info("Priprava na komprimaciu: " + file.getAbsolutePath());
                    files.add(file.getAbsolutePath());
                }
                File testZip = new File("test.zip");
                ZipUtilities.compress(files, testZip.getAbsolutePath());

                streamer.sendFile(testZip);
                long end = System.currentTimeMillis();

                System.out.println("System transfered in " + (end-start) + " ms");
                out.println("CLOSE");
                break;
            }

            if (fromServer.equals("READ_DATA")) {
                log.info("Client ready to receive data");
                long start = System.currentTimeMillis();
                out.println("test1MB.txt");
                streamer.readFile(new File("C:\\transport.txt"));
                //streamer.sendFile(new File("C:\\test1GB.txt"));
                long end = System.currentTimeMillis();

                double time = (end-start)/1000;
                System.out.println("System transfered in " + (end-start) + " ms");
                out.println("CLOSE");
                break;
            }

            if (fromServer.equals("SEND_INFO")) {
                ObjectOutputStream objectOut = new ObjectOutputStream(socket.getOutputStream());
                objectOut.writeObject(info);
                out.println("CLOSE");
                break;
            }

            if (fromServer.equals("CLOSE")) {
                break;
            }
        }

        out.close();
        in.close();
        stdIn.close();
        socket.close();
    }

    public static void main(String[] args) throws IOException {
        try {
            new TestClient();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
