package cpsc471.ftp.client.control;

import cpsc471.ftp.data.DataChannelServer;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * Implementation of the ControlClient interface
 */
public class ControlClientImpl implements ControlClient {

    private Logger logger = Logger.getLogger(this.getClass());

    private String domainName;

    private short port;

    private Socket socket;

    private PrintWriter socketWriter;

    private BufferedReader socketReader;

    /**
     * Create a ControlClient
     * @param domainName domainName name of server to which to connect
     * @param port port on server to which to connect
     * @throws IllegalArgumentException if domainName name isn't found
     */
    public ControlClientImpl(String domainName, short port)
            throws UnknownHostException, IOException {

        this.domainName = domainName;
        this.port = port;

        setSocket(new Socket(domainName, port));
    }

    /**
     * Basic constructor, for testing
     */
    public ControlClientImpl() {

        BasicConfigurator.configure(); // configure log4j
    }

    @Override
    public void ls() throws IOException {

        socketWriter.println("ls");
        DataChannelServer dataChannel = new DataChannelServer();
        socketWriter.println(dataChannel.getPort());
        socketWriter.flush();
        //dataChannel.accept(); // accept connection, returns when connection established
        // dataChannel.download(null); // will print to stdout
    }

    @Override
    public void put(String localFile)
        throws FileNotFoundException, IOException {

        put(new File(localFile));
    }

    /**
     * Upload a file to the server
     * @param localFile the file to upload
     * @throws FileNotFoundException file to upload
     */
    public void put(File localFile)
            throws FileNotFoundException, IOException {

        if(localFile.exists()) {
            socketWriter.println("put");
            socketWriter.println(localFile.getName());
            socketWriter.println(localFile.length());

            DataChannelServer dataChannel = new DataChannelServer();
            socketWriter.println(dataChannel.getPort());
            socketWriter.flush();
            // upload file, catch errors
        }
        else {
            throw new FileNotFoundException(
                    "File \"" + localFile.getName() + "\" does not exist"
            );
        }
    }

    @Override
    public void get(String remoteFile)
        throws FileNotFoundException, IOException {

        // send get request to server
        socketWriter.println("get");
        socketWriter.println(remoteFile);

        DataChannelServer dataChannel = new DataChannelServer();
        socketWriter.println(dataChannel.getPort());
        socketWriter.flush();

        String serverResponse = null;
        try {
            serverResponse = socketReader.readLine();
        }
        catch (IOException e) {
            logger.warn("Unable to read from socket: " + e.getMessage(), e);
        }

        if(!serverResponse.equals("connecting")) {
            throw new FileNotFoundException("Server could not find file.");
        }
        // download file, catch errors
        // this may not work b/c of waiting for response from server
    }

    @Override
    public void quit() {

        try {
            // send quit signal to server
            socketWriter.println("quit");
            socketWriter.flush();
            socket.close();
        }
        catch (IOException e) {
            logger.warn("Unable to close socket:" + e.getMessage(), e);
        }
    }

    // region Getters and Setters

    public String getDomainName() {
        return domainName;
    }

    public short getPort() {
        return port;
    }

    public Socket getSocket() {
        return socket;
    }

    /**
     * Sets socket and streams that read from socket
     * @param socket socket to set
     * @throws IOException if unable to open a stream into the socket
     */
    public void setSocket(Socket socket) throws IOException {

        this.socket = socket;
        socketWriter = new PrintWriter(socket.getOutputStream());
        socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    }
    // endregion
}

@@ -2940,36 +2940,21 @@
     
-String serverResponse = null
+long fileSize
 ;%0A  
@@ -2981,25 +2981,34 @@
     
-serverResponse = 
+fileSize = Long.parseLong(
 sock
@@ -3026,16 +3026,17 @@
 adLine()
+)
 ;%0A      
@@ -3063,32 +3063,68 @@
 OException e) %7B%0A
+            // if nothing in socket%0A
             logg
@@ -3194,25 +3194,24 @@
       %7D%0A
-%0A
         
 if(!serv
@@ -3206,50 +3206,101 @@
     
-if(!serverResponse.equals(%22connecting%22)) %7B
+catch(NumberFormatException e) %7B%0A            // if a value other than a file size is returned
 %0A   
@@ -3367,17 +3367,16 @@
 ind file
-.
 %22);%0A    
@@ -3373,32 +3373,33 @@
 le%22);%0A        %7D%0A
+%0A
         // downl

Read file size from server response