import org.eclipse.jetty.websocket.api.Callback;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Arrays;
import java.util.Scanner;

public class WebsocketChatClient {

	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
	private static final String TOPIC_NAME = "chat";

	private static volatile boolean running = true;

	// For testing with

	// Run a couple of these

	public static void main(String[] args) throws Exception {
		WebSocketClient client = new WebSocketClient();
		client.setIdleTimeout(Duration.ZERO);
		client.start();

		Session session = client.connect(new Listener(), URI.create("wss://wss.messagebus.org/websocket/" + TOPIC_NAME)).get();

		System.out.println("Connected to topic " + TOPIC_NAME);

		Scanner scanner = new Scanner(System.in);
		while (running) {
			try {
				String line = scanner.nextLine();
				session.sendBinary(ByteBuffer.wrap(line.getBytes(StandardCharsets.UTF_8)), Callback.NOOP);
			} catch (Exception e) {
				logger.error("Error in read/send loop", e);
				running = false;
				System.exit(24);
			}
		}
	}

	@WebSocket
	public static class Listener {

		@OnWebSocketMessage
		public void onMessage(Session session, ByteBuffer byteBuffer, Callback callback) {
			System.out.println("Received >> " + new String(byteBufferToArray(byteBuffer), StandardCharsets.UTF_8));
		}
	}

	public static byte[] byteBufferToArray(ByteBuffer byteBuffer) {
		int offset = byteBuffer.arrayOffset() + byteBuffer.position(); // Account for position and offset
		int length = byteBuffer.remaining(); // Number of bytes remaining to read
		return Arrays.copyOfRange(byteBuffer.array(), offset, offset + length);
	}
}
