package kvstore;

import static kvstore.KVConstants.DEL_REQ;
import static kvstore.KVConstants.ERROR_COULD_NOT_CONNECT;
import static kvstore.KVConstants.ERROR_COULD_NOT_CREATE_SOCKET;
import static kvstore.KVConstants.ERROR_INVALID_KEY;
import static kvstore.KVConstants.ERROR_INVALID_VALUE;
import static kvstore.KVConstants.GET_REQ;
import static kvstore.KVConstants.PUT_REQ;
import static kvstore.KVConstants.RESP;
import static kvstore.KVConstants.SUCCESS;

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

/**
 * Client API used to issue requests to key-value server.
 */
public class KVClient implements KeyValueInterface {

    public String server;
    public int port;

    /**
     * Constructs a KVClient connected to a server.
     *
     * @param server is the DNS reference to the server
     * @param port is the port on which the server is listening
     */
    public KVClient(String server, int port) {
        this.server = server;
        this.port = port;
    }

    /**
     * Creates a socket connected to the server to make a request.
     *
     * @return Socket connected to server
     * @throws KVException if unable to create or connect socket
     */
    public Socket connectHost() throws KVException {
        // implement me
        return null;
    }

    /**
     * Closes a socket.
     * Best effort, ignores error since the response has already been received.
     *
     * @param  sock Socket to be closed
     */
    public void closeHost(Socket sock) {
        // implement me
    }

    /**
     * Issues a PUT request to the server.
     *
     * @param  key String to put in server as key
     * @throws KVException if the request was not successful in any way
     */
    @Override
    public void put(String key, String value) throws KVException {
        // implement me
    }

    /**
     * Issues a GET request to the server.
     *
     * @param  key String to get value for in server
     * @return String value associated with key
     * @throws KVException if the request was not successful in any way
     */
    @Override
    public String get(String key) throws KVException {
        // implement me
        return null;
    }

    /**
     * Issues a DEL request to the server.
     *
     * @param  key String to delete value for in server
     * @throws KVException if the request was not successful in any way
     */
    @Override
    public void del(String key) throws KVException {
        // implement me
    }


}

@@ -547,16 +547,46 @@
 ption;%0A%0A
+import java.net.InetAddress;%0A%0A
 /**%0A * C
@@ -1304,39 +1304,320 @@
 n %7B%0A        
-// implement me
+Socket ret;%0A%0A        try %7B%0A            ret = new Socket(InetAddress.getByName(server), port);%0A        %7D catch (IOException e) %7B%0A            throw new KVException(ERROR_COULD_NOT_CONNECT);%0A        %7D catch (Exception e) %7B%0A            throw new KVException(ERROR_COULD_NOT_CREATE_SOCKET);%0A        %7D%0A
 %0A        ret
@@ -1612,36 +1612,35 @@
 %0A        return 
-null
+ret
 ;%0A    %7D%0A%0A    /**
@@ -1844,39 +1844,88 @@
 ) %7B%0A        
-// implement me
+try %7B%0A            sock.close();%0A        %7D catch (Exception e) %7B%7D
 %0A    %7D%0A%0A    
@@ -2193,39 +2193,304 @@
 n %7B%0A        
-// implement me
+Socket s = connectHost();%0A        KVMessage msg = new KVMessage(PUT_REQ);%0A        msg.setKey(key);%0A        msg.setValue(value);%0A        msg.sendMessage(s);%0A        msg = new KVMessage(s);%0A        if(msg.getMessage() != SUCCESS)%0A            throw new KVException(msg.getMessage());
 %0A    %7D%0A%0A    
@@ -2797,39 +2797,267 @@
 n %7B%0A        
-// implement me
+Socket s = connectHost();%0A        KVMessage msg = new KVMessage(GET_REQ);%0A        msg.setKey(key);%0A        msg.sendMessage(s);%0A        msg = new KVMessage(s);%0A        if(msg.getKey() != key)%0A            throw new KVException(msg.getMessage());
 %0A        ret
@@ -3064,12 +3064,22 @@
 urn 
-null
+msg.getValue()
 ;%0A  
@@ -3356,23 +3356,259 @@
     
-// implement me
+Socket s = connectHost();%0A        KVMessage msg = new KVMessage(DEL_REQ);%0A        msg.setKey(key);%0A        msg.sendMessage(s);%0A        msg = new KVMessage(s);%0A        if(msg.getMessage() != SUCCESS)%0A            throw new KVException(msg.getMessage());
 %0A   

Implement KVClient.