package org.pitest.util;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Callable;

import org.pitest.functional.SideEffect1;

class SocketReadingCallable implements Callable<ExitCode> {

  private final SideEffect1<SafeDataOutputStream> sendInitialData;
  private final ReceiveStrategy                   receive;
  private final ServerSocket                      socket;

  SocketReadingCallable(final ServerSocket socket,
      final SideEffect1<SafeDataOutputStream> sendInitialData,
      final ReceiveStrategy receive) {
    this.socket = socket;
    this.sendInitialData = sendInitialData;
    this.receive = receive;
  }

  @Override
  public ExitCode call() throws Exception {
    final Socket clientSocket = this.socket.accept();
    ExitCode exitCode = ExitCode.UNKNOWN_ERROR;
    try {
      final BufferedInputStream bif = new BufferedInputStream(
          clientSocket.getInputStream());

      sendDataToMinion(clientSocket);

      final SafeDataInputStream is = new SafeDataInputStream(bif);
      exitCode = receiveResults(is);

      bif.close();

    } catch (final IOException e) {
      throw Unchecked.translateCheckedException(e);
    } finally {
      try {
        clientSocket.close();
        this.socket.close();
      } catch (final IOException e) {
        throw Unchecked.translateCheckedException(e);
      }
    }

    return exitCode;
  }

  private void sendDataToMinion(final Socket clientSocket) throws IOException {
    final OutputStream os = clientSocket.getOutputStream();
    final SafeDataOutputStream dos = new SafeDataOutputStream(os);
    this.sendInitialData.apply(dos);
  }

  private ExitCode receiveResults(final SafeDataInputStream is) {
    byte control = is.readByte();
    while (control != Id.DONE) {
      this.receive.apply(control, is);
      control = is.readByte();
    }
    return ExitCode.fromCode(is.readInt());

  }

}
@@ -810,22 +810,21 @@
 n %7B%0A    
-final 
+try (
 Socket c
@@ -861,80 +861,23 @@
 pt()
-;
+) %7B
 %0A    
-ExitCode exitCode = ExitCode.UNKNOWN_ERROR;%0A    try %7B%0A      final 
+  try (
 Buff
@@ -963,25 +963,27 @@
 tream())
-;
+) %7B
 %0A%0A      
 sendData
@@ -974,16 +974,18 @@
 %0A%0A      
+  
 sendData
@@ -1005,24 +1005,26 @@
 ntSocket);%0A%0A
+  
       final 
@@ -1088,18 +1088,16 @@
     
-exitCode =
+  return
  rec
@@ -1117,29 +1117,10 @@
 s);%0A
-%0A
   
-    bif.close();%0A%0A
     
@@ -1147,24 +1147,26 @@
 eption e) %7B%0A
+  
       throw 
@@ -1201,24 +1201,32 @@
 ception(e);%0A
+      %7D%0A
     %7D finall
@@ -1245,38 +1245,8 @@
 y %7B%0A
-        clientSocket.close();%0A
     
@@ -1379,30 +1379,8 @@
    %7D
-%0A%0A    return exitCode;
 %0A  %7D

use java 7 features