package vs;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import jakarta.jms.Connection;
import jakarta.jms.ConnectionFactory;
import jakarta.jms.JMSException;
import jakarta.jms.Message;
import jakarta.jms.MessageConsumer;
import jakarta.jms.MessageListener;
import jakarta.jms.Queue;
import jakarta.jms.Session;
import jakarta.jms.TextMessage;
import jakarta.jms.Topic;
import jakarta.xml.bind.DatatypeConverter;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class PasswordCandidateValidator implements MessageListener {
	private static int messageCounter = 0;
	private final byte[] target;
	private final MessageDigest dig;
	private Connection connection;
	private Session session;
	private MessageConsumer taskConsumer;
	private MessageConsumer successConsumer;
	private boolean stopped = false;

	public PasswordCandidateValidator(String target) throws NamingException, JMSException, NoSuchAlgorithmException {
		this.dig = MessageDigest.getInstance("SHA-256");
		this.target = DatatypeConverter.parseHexBinary(target);
		Context ctx = new InitialContext();
		ConnectionFactory factory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
		Queue queue = (Queue) ctx.lookup(Conf.TASK_QUEUE);
		this.connection = factory.createConnection();
		this.session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		this.taskConsumer = this.session.createConsumer(queue);
		this.taskConsumer.setMessageListener(this);
		Topic successTopic = (Topic) ctx.lookup(Conf.SUCCESS_TOPIC);
		this.successConsumer = this.session.createConsumer(successTopic);
		this.successConsumer.setMessageListener(new MessageListener() {
			@Override
			public void onMessage(Message message) {
				PasswordCandidateValidator.this.stopped = true;
				System.out.println("Password gefunden. PasswordCandidateValidator wird gestoppt.");

			}
		});
		this.connection.start();
	}

	@Override
	public void onMessage(Message message) {
		synchronized (PasswordCandidateValidator.class) {
			if (PasswordCandidateValidator.messageCounter++ >= 99) {
				System.out.println(System.currentTimeMillis());
				PasswordCandidateValidator.messageCounter = 0;
			}
		}
		if (message instanceof TextMessage) {
			TextMessage task = (TextMessage) message;
			try {
				byte[] hash = this.dig.digest(task.getText().getBytes());
				if (Arrays.equals(hash, this.target)) {
					System.out.println("Lösung gefunden: " + task.getText());
				}
			} catch (JMSException e) {
				System.err.println(e);
			}
		}
	}

	public static void main(String[] args) {
		PasswordCandidateValidator node = null;
		try {
			node = new PasswordCandidateValidator("865ae56c298c677e9d4987fe13268fa915bd041646526c595d293d5448481443");
			while (!node.stopped) {
				Thread.sleep(1000);
			}
		} catch (InterruptedException | NamingException | JMSException | NoSuchAlgorithmException e) {
			System.err.println(e);
		} finally {
			try {
				if ((node != null) && (node.taskConsumer != null)) {
					node.taskConsumer.close();
				}
				if ((node != null) && (node.session != null)) {
					node.session.close();
				}
				if ((node != null) && (node.connection != null)) {
					node.connection.close();
				}
			} catch (JMSException e) {
				System.err.println(e);
			}
		}
	}
}
