package i5.las2peer.security;

import i5.las2peer.api.exceptions.EnvelopeAlreadyExistsException;
import i5.las2peer.api.exceptions.StorageException;
import i5.las2peer.logging.NodeObserver.Event;
import i5.las2peer.p2p.AgentNotKnownException;
import i5.las2peer.p2p.Node;
import i5.las2peer.persistency.Envelope;
import i5.las2peer.tools.CryptoException;
import i5.las2peer.tools.SerializationException;

/**
 * Maps usernames and emails to {@link UserAgent}s.
 *
 */
public class UserAgentManager {

	private static final String PREFIX_USER_NAME = "USER_NAME-";
	private static final String PREFIX_USER_MAIL = "USER_MAIL-";

	private Node node;

	public UserAgentManager(Node node) {
		this.node = node;
	}

	/**
	 * Stores login name and email of an user agent to the network
	 * 
	 * @param agent an unlocked UserAgent
	 * @throws DuplicateEmailException
	 * @throws DuplicateLoginNameException
	 * @throws AgentLockedException
	 */
	public void registerUserAgent(UserAgent agent)
			throws DuplicateEmailException, DuplicateLoginNameException, AgentLockedException {
		if (agent.isLocked()) {
			throw new AgentLockedException("Only unlocked Agents can be registered!");
		}
		Long content = agent.getId();
		if (agent.hasLogin()) {
			try {
				// FIXME No Context! Not executed in a L2pThread environment!
//				Envelope envName = Context.getCurrent()
//						.createUnencryptedEnvelope(PREFIX_USER_NAME + agent.getLoginName().toLowerCase(), content);
				Envelope envName = node.createUnencryptedEnvelope(PREFIX_USER_NAME + agent.getLoginName().toLowerCase(),
						content);
				node.storeEnvelope(envName, agent);
			} catch (EnvelopeAlreadyExistsException e) {
				throw new DuplicateLoginNameException();
			} catch (SerializationException | CryptoException | StorageException e) {
				node.observerNotice(Event.NODE_ERROR, "Envelope error while updating user list: " + e);
			}
		}

		if (agent.hasEmail()) {
			try {
				Envelope envMail = Context.getCurrent()
						.createUnencryptedEnvelope(PREFIX_USER_MAIL + agent.getEmail().toLowerCase(), content);
				node.storeEnvelope(envMail, agent);
			} catch (EnvelopeAlreadyExistsException e) {
				throw new DuplicateEmailException();
			} catch (SerializationException | CryptoException | StorageException e) {
				node.observerNotice(Event.NODE_ERROR, "Envelope error while updating user list: " + e);
			}
		}
	}

	/**
	 * updates login name and email of an user
	 * 
	 * @param agent
	 * @throws AgentLockedException
	 * @throws DuplicateEmailException
	 * @throws DuplicateLoginNameException
	 */
	public void updateUserAgent(UserAgent agent)
			throws AgentLockedException, DuplicateEmailException, DuplicateLoginNameException {
		registerUserAgent(agent);
	}

	/**
	 * get an {@link UserAgent}'s id by login name
	 * 
	 * @param name
	 * @return
	 * @throws AgentNotKnownException
	 */
	public long getAgentIdByLogin(String name) throws AgentNotKnownException {
		try {
			Envelope env = Context.getCurrent().fetchEnvelope(PREFIX_USER_NAME + name.toLowerCase());
			return (Long) env.getContent();
		} catch (StorageException e) {
			throw new AgentNotKnownException("Username not found!", e);
		} catch (SerializationException | CryptoException e) {
			throw new AgentNotKnownException("Could not read agent id from storage");
		}
	}

	/**
	 * get an {@link UserAgent}'s id by email address
	 * 
	 * @param email
	 * @return
	 * @throws AgentNotKnownException
	 */
	public long getAgentIdByEmail(String email) throws AgentNotKnownException {
		try {
			Envelope env = Context.getCurrent().fetchEnvelope(PREFIX_USER_MAIL + email.toLowerCase());
			return (Long) env.getContent();
		} catch (StorageException e) {
			throw new AgentNotKnownException("Email not found!", e);
		} catch (SerializationException | CryptoException e) {
			throw new AgentNotKnownException("Could not read email from storage");
		}
	}
}

@@ -1243,220 +1243,8 @@
 y %7B%0A
-%09%09%09%09// FIXME No Context! Not executed in a L2pThread environment!%0A//%09%09%09%09Envelope envName = Context.getCurrent()%0A//%09%09%09%09%09%09.createUnencryptedEnvelope(PREFIX_USER_NAME + agent.getLoginName().toLowerCase(), content);%0A
 %09%09%09%09
@@ -1348,16 +1348,16 @@
 Case(),%0A
+
 %09%09%09%09%09%09co
@@ -1738,35 +1738,12 @@
 l = 
-Context.getCurrent()%0A%09%09%09%09%09%09
+node
 .cre
@@ -1815,17 +1815,23 @@
 rCase(),
- 
+%0A%09%09%09%09%09%09
 content)
@@ -2721,36 +2721,20 @@
 e env = 
-Context.getCurrent()
+node
 .fetchEn
@@ -3290,28 +3290,12 @@
 v = 
-Context.getCurrent()
+node
 .fet

fix missing context issue