import java.net.DatagramPacket;
import java.util.logging.Level;

public class SW extends ARQAbst {
  public SW(Socket socket) {
    super(socket);
  }

  public SW(Socket socket, int sessionID) {
    super(socket, sessionID);
  }

  @Override
  public void closeConnection() {  }

  @Override
  public boolean data_req(byte[] hlData, int hlSize, boolean lastTransmission) {
    byte[] sendData = generateDataPacket(hlData, hlSize);
    socket.sendPacket(sendData);
    logger.log(Level.FINER, "Client-SW: Packet sent  + wait for ACK");
    return waitForAck(0 );
  }

  @Override
  protected boolean waitForAck(int packetNr) {
    socket.setTimeout(1000); // Tbd: Timeout
    DatagramPacket ackPacket;
    try {
      ackPacket = socket.receivePacket();
    } catch (TimeoutException e) {
      throw new RuntimeException(e);
    }
    String marker = new String(ackPacket.getData(), 0, 4);
    logger.log(Level.FINER, "Client-SW: Packet " + marker + " received");
    return marker.equals("ACK");
  }
  @Override
  protected int getPacketNr(DatagramPacket packet) {return 0;  }

  @Override
  protected void getAckData(DatagramPacket packet) {
  }

  @Override
  protected int getSessionID(DatagramPacket packet) {return 0;  }

  @Override
  protected byte[] generateDataPacket(byte[] sendData, int dataSize) {
    return sendData;
  }

  // ******************************** Receiver *****************************************************
  @Override
  public byte[] data_ind_req(int... values) throws TimeoutException {
    DatagramPacket dataPacket;

    try {
      dataPacket = socket.receivePacket();
      logger.log(Level.FINER, "Server-SW: Data packet received");
    } catch (TimeoutException e) {
      logger.log(Level.FINER, "Data packet receive timed out");
      throw new TimeoutException("Server-SW: receive time out");
    }
    sendAck(0);
    return dataPacket.getData();
  }

  @Override
  byte[] generateAckPacket(int packetNr) {
    return  ("ACK" + packetNr).getBytes();
  }

  @Override
  void sendAck(int nr) {
    socket.sendPacket(generateAckPacket(nr));
    logger.log(Level.FINER, "Server SW: ACK sent");
  }

  @Override
  boolean checkStart(DatagramPacket packet) {return false;  }
}
