package com.cardshifter.server.main;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import com.cardshifter.api.incoming.LoginMessage;
import com.cardshifter.api.outgoing.ResetAvailableActionsMessage;
import net.zomis.cardshifter.ecs.usage.CardshifterIO;
import org.junit.Assert;
import com.cardshifter.api.messages.Message;
import com.cardshifter.api.outgoing.ServerErrorMessage;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestClient {
private final Socket socket;
private final ObjectMapper mapper;
private final InputStream in;
private final OutputStream out;
private final LinkedBlockingQueue<Message> messages = new LinkedBlockingQueue<>();
private final Thread thread;
private String name = "";
public TestClient(int port) throws UnknownHostException, IOException {
this.socket = new Socket("127.0.0.1", port);
this.mapper = CardshifterIO.mapper();
out = socket.getOutputStream();
in = socket.getInputStream();
mapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
mapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
thread = new Thread(this::listen);
thread.start();
}
public String getName() {
return name;
}
private void listen() {
try {
MappingIterator<Message> values = mapper.readValues(new JsonFactory().createParser(in), Message.class);
while (values.hasNext()) {
Message msg = values.next();
System.out.println("Incoming message " + msg);
messages.offer(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(Message message) throws JsonGenerationException, JsonMappingException, IOException {
if (message instanceof LoginMessage) {
name = ((LoginMessage) message).getUsername();
}
mapper.writeValue(out, message);
}
public <T> List<T> awaitMany(int count, Class<T> class1) throws JsonParseException, JsonProcessingException, IOException, InterruptedException {
List<T> result = new ArrayList<>();
for (int i = 0; i < count; i++) {
result.add(await(class1));
}
assertEquals(count, result.size());
return result;
}
public <T> T await(Class<T> class1) throws IOException, InterruptedException {
Message message = messages.take();
if (!class1.isAssignableFrom(message.getClass())) {
Assert.fail("Expected " + class1 + " but was " + message);
}
return class1.cast(message);
}
public void disconnect() throws IOException {
socket.close();
thread.interrupt();
}
public <T extends Message> T awaitUntil(Class<T> messageClass) throws InterruptedException, IOException {
Message message;
do {
message = await(Message.class);
} while (!messageClass.isAssignableFrom(message.getClass()));
return messageClass.cast(message);
}
}