package protocolP2P;
import protocolP2P.CodeType;
import localException.ProtocolError;
import java.util.HashMap;
import java.util.Map;
import java.lang.Byte;

/** Request/Response code enum.
 * @author	Louis Royer
 * @author	Flavien Haas
 * @author	JS Auge
 * @version	1.0
 */
public enum RequestResponseCode {
	LIST_REQUEST(CodeType.REQUEST, (byte)0x00),
	LOAD_REQUEST(CodeType.REQUEST, (byte)0x01),
	HASH_REQUEST(CodeType.REQUEST, (byte)0x02),
	DISCOVER_REQUEST(CodeType.REQUEST_TRACKER, (byte)0x03),
	REGISTER(CodeType.REQUEST_TRACKER, (byte)0x04),
	UNREGISTER(CodeType.REQUEST_TRACKER, (byte)0x05),
	RATIO_REQUEST(CodeType.REQUEST_TRACKER, (byte)0x06),
	UPDATE_RATIO(CodeType.REQUEST_TRACKER, (byte)0x07),
	SIZE_REQUEST(CodeType.REQUEST, (byte)0x08),
	LIST_RESPONSE(CodeType.RESPONSE, (byte)0x80),
	LOAD_RESPONSE(CodeType.RESPONSE, (byte)0x81),
	HASH_RESPONSE(CodeType.RESPONSE, (byte)0x82),
	DISCOVER_RESPONSE(CodeType.RESPONSE, (byte)0x83),
	RATIO_RESPONSE(CodeType.RESPONSE, (byte)0x86),
	DENIED(CodeType.RESPONSE, (byte)0x87),
	SIZE_RESPONSE(CodeType.RESPONSE, (byte)0x88),
	VERSION_ERROR(CodeType.ERROR, (byte)0xC0),
	PROTOCOL_ERROR(CodeType.ERROR, (byte)0xC1),
	INTERNAL_ERROR(CodeType.ERROR, (byte)0xC2),
	EMPTY_DIRECTORY(CodeType.ERROR, (byte)0xC3),
	NOT_FOUND(CodeType.ERROR, (byte)0xC4),
	EMPTY_FILE(CodeType.ERROR, (byte)0xC5),
	NOT_A_TRACKER(CodeType.ERROR, (byte)0xC6),
	UNKNOWN_HOST(CodeType.ERROR, (byte)0xC7);

	public final CodeType codeType;
	public final byte codeValue;
	protected final static int RRCODE_POSITION = 1;

	/* To be able to convert code to enum */
	private static final Map<Byte, RequestResponseCode> BY_CODE = new HashMap<>();
	/* Initialization of HashMap */
	static {
		for (RequestResponseCode r: values()) {
			assert !BY_CODE.containsKey(Byte.valueOf(r.codeValue)) : "Duplicate in " + RequestResponseCode.class.getCanonicalName();
			BY_CODE.put(Byte.valueOf(r.codeValue), r);
		}
	}

	/** Private constructor
	 * @param codeType	type of code (request or response)
	 * @param codeValue	value of the element in Packet
	 * @return	enum element
	 */
	private RequestResponseCode(CodeType codeType, byte codeValue) {
		this.codeType = codeType;
		this.codeValue = codeValue;
	}

	/** Gives enum from Packet code.
	 * @param code	value of the element in packet
	 * @return	enum element
	 * @throws	ProtocolError
	 */
	protected static RequestResponseCode fromCode(byte code) throws ProtocolError {
		RequestResponseCode r = BY_CODE.get(Byte.valueOf(code));
		if (r == null) {
			throw new ProtocolError();
		}
		return r;
	}


}
