// Path: src/main/java/com/github/koraktor/steamcondenser/servers/sockets/SourceSocket.java
// public class SourceSocket extends QuerySocket {
// 
//     protected static final Logger LOG = LoggerFactory.getLogger(SourceSocket.class);
// 
//     /**
//      * Creates a new socket to communicate with the server on the given IP
//      * address and port
//      *
//      * @param ipAddress Either the IP address or the DNS name of the server
//      * @param portNumber The port the server is listening on
//      * @throws SteamCondenserException if the socket cannot be opened
//      */
//     public SourceSocket(InetAddress ipAddress, int portNumber)
//             throws SteamCondenserException {
//         super(ipAddress, portNumber);
//     }
// 
//     /**
//      * Reads a packet from the socket
//      * <p>
//      * The Source query protocol specifies a maximum packet size of 1,400
//      * bytes. Bigger packets will be split over several UDP packets. This
//      * method reassembles split packets into single packet objects.
//      * Additionally Source may compress big packets using bzip2. Those packets
//      * will be compressed.
//      *
//      * @return SteamPacket The packet replied from the server
//      * @throws SteamCondenserException if an error occurs while communicating
//      *         with the server
//      * @throws TimeoutException if the request times out
//      */
//     public SteamPacket getReply()
//             throws SteamCondenserException, TimeoutException {
//         int bytesRead;
//         boolean isCompressed = false;
//         SteamPacket packet;
// 
//         bytesRead = this.receivePacket(1400);
// 
//         if(this.packetIsSplit()) {
//             byte[] splitData;
//             int packetCount, packetNumber, requestId, splitSize;
//             int packetChecksum = 0;
//             ArrayList<byte[]> splitPackets = new ArrayList<>();
// 
//             do {
//                 requestId = Integer.reverseBytes(this.buffer.getInt());
//                 isCompressed = ((requestId & 0x80000000) != 0);
//                 packetCount = this.buffer.get();
//                 packetNumber = this.buffer.get() + 1;
// 
//                 if(isCompressed) {
//                     splitSize = Integer.reverseBytes(this.buffer.getInt());
//                     packetChecksum = Integer.reverseBytes(this.buffer.getInt());
//                 } else {
//                     splitSize = Short.reverseBytes(this.buffer.getShort());
//                 }
// 
//                 splitData = new byte[Math.min(splitSize, this.buffer.remaining())];
//                 this.buffer.get(splitData);
//                 splitPackets.ensureCapacity(packetCount);
//                 splitPackets.add(packetNumber - 1, splitData);
// 
//                 if(splitPackets.size() < packetCount) {
//                     try {
//                         bytesRead = this.receivePacket();
//                     } catch(TimeoutException e) {
//                         bytesRead = 0;
//                     }
//                 } else {
//                     bytesRead = 0;
//                 }
// 
//                 LOG.info("Received packet #" + packetNumber + " of " + packetCount + " for request ID " + requestId + ".");
//             } while(bytesRead > 0 && this.packetIsSplit());
// 
//             if(isCompressed) {
//                 packet = SteamPacketFactory.reassemblePacket(splitPackets, true, splitSize, packetChecksum);
//             } else {
//                 packet = SteamPacketFactory.reassemblePacket(splitPackets);
//             }
//         } else {
//             packet = this.getPacketFromData();
//         }
// 
//         this.buffer.flip();
// 
//         if(isCompressed) {
//             LOG.info("Received compressed reply of type \"" + packet.getClass().getSimpleName() + "\"");
//         } else {
//             LOG.info("Received reply of type \"" + packet.getClass().getSimpleName() + "\"");
//         }
// 
//         return packet;
//     }
// }


import java.net.InetAddress;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.github.koraktor.steamcondenser.exceptions.RCONNoAuthException;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONAuthRequestPacket;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONAuthResponse;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONExecRequestPacket;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONExecResponsePacket;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONTerminator;
import com.github.koraktor.steamcondenser.servers.sockets.RCONSocket;
import com.github.koraktor.steamcondenser.servers.sockets.SourceSocket;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.verifyNew;
import static org.powermock.api.mockito.PowerMockito.whenNew;
/*
 * This code is free software; you can redistribute it and/or modify it under
 * the terms of the new BSD License.
 *
 * Copyright (c) 2012-2020, Sebastian Staudt
 */

package com.github.koraktor.steamcondenser.servers;






/**
 *
 *
 * @author Sebastian Staudt
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest(SourceServer.class)
public class SourceServerTest {

    @Rule
    private ExpectedException exception = ExpectedException.none();

    private static InetAddress LOCALHOST;

    private RCONSocket rconSocket;

    private SourceServer server;

// Path: src/main/java/com/github/koraktor/steamcondenser/servers/sockets/SourceSocket.java
// public class SourceSocket extends QuerySocket {
// 
//     protected static final Logger LOG = LoggerFactory.getLogger(SourceSocket.class);
// 
//     /**
//      * Creates a new socket to communicate with the server on the given IP
//      * address and port
//      *
//      * @param ipAddress Either the IP address or the DNS name of the server
//      * @param portNumber The port the server is listening on
//      * @throws SteamCondenserException if the socket cannot be opened
//      */
//     public SourceSocket(InetAddress ipAddress, int portNumber)
//             throws SteamCondenserException {
//         super(ipAddress, portNumber);
//     }
// 
//     /**
//      * Reads a packet from the socket
//      * <p>
//      * The Source query protocol specifies a maximum packet size of 1,400
//      * bytes. Bigger packets will be split over several UDP packets. This
//      * method reassembles split packets into single packet objects.
//      * Additionally Source may compress big packets using bzip2. Those packets
//      * will be compressed.
//      *
//      * @return SteamPacket The packet replied from the server
//      * @throws SteamCondenserException if an error occurs while communicating
//      *         with the server
//      * @throws TimeoutException if the request times out
//      */
//     public SteamPacket getReply()
//             throws SteamCondenserException, TimeoutException {
//         int bytesRead;
//         boolean isCompressed = false;
//         SteamPacket packet;
// 
//         bytesRead = this.receivePacket(1400);
// 
//         if(this.packetIsSplit()) {
//             byte[] splitData;
//             int packetCount, packetNumber, requestId, splitSize;
//             int packetChecksum = 0;
//             ArrayList<byte[]> splitPackets = new ArrayList<>();
// 
//             do {
//                 requestId = Integer.reverseBytes(this.buffer.getInt());
//                 isCompressed = ((requestId & 0x80000000) != 0);
//                 packetCount = this.buffer.get();
//                 packetNumber = this.buffer.get() + 1;
// 
//                 if(isCompressed) {
//                     splitSize = Integer.reverseBytes(this.buffer.getInt());
//                     packetChecksum = Integer.reverseBytes(this.buffer.getInt());
//                 } else {
//                     splitSize = Short.reverseBytes(this.buffer.getShort());
//                 }
// 
//                 splitData = new byte[Math.min(splitSize, this.buffer.remaining())];
//                 this.buffer.get(splitData);
//                 splitPackets.ensureCapacity(packetCount);
//                 splitPackets.add(packetNumber - 1, splitData);
// 
//                 if(splitPackets.size() < packetCount) {
//                     try {
//                         bytesRead = this.receivePacket();
//                     } catch(TimeoutException e) {
//                         bytesRead = 0;
//                     }
//                 } else {
//                     bytesRead = 0;
//                 }
// 
//                 LOG.info("Received packet #" + packetNumber + " of " + packetCount + " for request ID " + requestId + ".");
//             } while(bytesRead > 0 && this.packetIsSplit());
// 
//             if(isCompressed) {
//                 packet = SteamPacketFactory.reassemblePacket(splitPackets, true, splitSize, packetChecksum);
//             } else {
//                 packet = SteamPacketFactory.reassemblePacket(splitPackets);
//             }
//         } else {
//             packet = this.getPacketFromData();
//         }
// 
//         this.buffer.flip();
// 
//         if(isCompressed) {
//             LOG.info("Received compressed reply of type \"" + packet.getClass().getSimpleName() + "\"");
//         } else {
//             LOG.info("Received reply of type \"" + packet.getClass().getSimpleName() + "\"");
//         }
// 
//         return packet;
//     }
// }


// Path: src/test/java/com/github/koraktor/steamcondenser/servers/SourceServerTest.java
import java.net.InetAddress;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.github.koraktor.steamcondenser.exceptions.RCONNoAuthException;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONAuthRequestPacket;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONAuthResponse;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONExecRequestPacket;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONExecResponsePacket;
import com.github.koraktor.steamcondenser.servers.packets.rcon.RCONTerminator;
import com.github.koraktor.steamcondenser.servers.sockets.RCONSocket;
import com.github.koraktor.steamcondenser.servers.sockets.SourceSocket;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.verifyNew;
import static org.powermock.api.mockito.PowerMockito.whenNew;

/*
 * This code is free software; you can redistribute it and/or modify it under
 * the terms of the new BSD License.
 *
 * Copyright (c) 2012-2020, Sebastian Staudt
 */

package com.github.koraktor.steamcondenser.servers;






/**
 *
 *
 * @author Sebastian Staudt
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest(SourceServer.class)
public class SourceServerTest {

    @Rule
    private ExpectedException exception = ExpectedException.none();

    private static InetAddress LOCALHOST;

    private RCONSocket rconSocket;

    private SourceServer server;

    private SourceSocket socket;