package com.dumbster.smtp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

public class ClientSession implements Runnable {

    private IOSource socket;
    private MailStore mailStore;
    private MailMessage msg;
    private Response smtpResponse;

    public ClientSession(IOSource socket, MailStore mailStore) {
        this.socket = socket;
        this.mailStore = mailStore;
        this.msg = new MailMessage();
        Request smtpRequest = Request.initialRequest();
        smtpResponse = smtpRequest.execute(mailStore, msg);
    }

    private void sessionLoop() throws IOException {
        PrintWriter out = socket.getOutputStream();
        out.flush();
        BufferedReader input = socket.getInputStream();
        sendResponse(out, smtpResponse);
        SmtpState smtpState = smtpResponse.getNextState();

        String line;
        while (smtpState != SmtpState.CONNECT && ((line = input.readLine()) != null)) {
            Request request = Request.createRequest(smtpState, line);
            Response response = request.execute(mailStore, msg);
            storeInputInMessage(request, response);
            sendResponse(out, response);
            smtpState = response.getNextState();
            saveAndRefreshMessageIfComplete(smtpState);
        }
    }

    private void saveAndRefreshMessageIfComplete(SmtpState smtpState) {
        if (smtpState == SmtpState.QUIT) {
            mailStore.addMessage(msg);
            msg = new MailMessage();
        }
    }

    private void storeInputInMessage(Request request, Response response) {
        String params = request.getParams();
        if (params != null) {
            if (SmtpState.DATA_HDR.equals(response.getNextState())) {
                int headerNameEnd = params.indexOf(':');
                if (headerNameEnd >= 0) {
                    String name = params.substring(0, headerNameEnd).trim();
                    String value = params.substring(headerNameEnd + 1).trim();
                    msg.addHeader(name, value);
                }
            } else if (SmtpState.DATA_BODY == response.getNextState()) {
                msg.appendBody(params);
            }
        }
    }

    private static void sendResponse(PrintWriter out, Response smtpResponse) {
        if (smtpResponse.getCode() > 0) {
            int code = smtpResponse.getCode();
            String message = smtpResponse.getMessage();
            out.print(code + " " + message + "\r\n");
            out.flush();
        }
    }

    public void run() {
        try {
            sessionLoop();
        } catch (Exception ignored) {
        } finally {
            try {
                socket.close();
            } catch (Exception ignored) {
            }
        }
    }

}

@@ -1663,30 +1663,45 @@
 if (
-params != null) %7B%0A    
+null == params)%0A            return;%0A%0A
     
@@ -1762,32 +1762,253 @@
 e())) %7B%0A        
+    addDataHeader(params);%0A            return;%0A        %7D%0A%0A        if (SmtpState.DATA_BODY == response.getNextState()) %7B%0A            msg.appendBody(params);%0A        %7D%0A    %7D%0A%0A    private void addDataHeader(String params) %7B%0A
         int head
@@ -2040,24 +2040,16 @@
 f(':');%0A
-        
         
@@ -2067,17 +2067,16 @@
 ameEnd %3E
-=
  0) %7B%0A  
@@ -2081,32 +2081,24 @@
             
-       
- 
 String name 
@@ -2138,32 +2138,24 @@
 nd).trim();%0A
-        
             
@@ -2221,32 +2221,24 @@
             
-     
-   
 msg.addHeade
@@ -2257,153 +2257,8 @@
 e);%0A
-                %7D%0A            %7D else if (SmtpState.DATA_BODY == response.getNextState()) %7B%0A                msg.appendBody(params);%0A            %7D%0A
     

extracted a method