package server;

import java.util.concurrent.TimeUnit;

public class User {
	
	private String m_queueName;
	private String m_userName;
	private long m_lastTime;
	private boolean m_awaitingResponse;
	final public static long PING_INTERVAL = 5000;
	final public static long CONNECTION_TIMEOUT = 7500;
	final public static String[] TABLE_HEADERS = { "Queue Name", "User Name", "Last Response" };
	
	public User(String queueName) {
		this(queueName, null);
	}
	
	public User(String queueName, String userName) {
		if(queueName == null) { throw new IllegalArgumentException("Queue name cannot be null for User"); }
		
		m_queueName = queueName;
		m_userName = userName;
		
		m_lastTime = System.currentTimeMillis();
		m_awaitingResponse = false;
	}
	
	// get the user's queue name
	public String getQueueName() {
		return m_queueName;
	}
	

	// get the user's name
	public String getUserName() {
		return m_userName;
	}
	
	// set the user's name
	public void setUserName(String userName) {
		m_userName = userName;
	}
	
	// check if the server is awaiting a response from the user
	public boolean isAwaitingResponse() {
		return m_awaitingResponse;
	}
	
	// update ping-related variables when a pong is received from the user
	public boolean ping() {
		if(!m_awaitingResponse && System.currentTimeMillis() > m_lastTime + PING_INTERVAL) { 
			m_lastTime = System.currentTimeMillis();
			m_awaitingResponse = true;
			return true;
		}
		return false;
	}
	
	// update the ping-related variables after a pong is sent to the user
	public void pong() {
		m_lastTime = System.currentTimeMillis();
		m_awaitingResponse = false;
	}
	
	// check if the connection to the user has timed out
	public boolean checkTimeout() {
		return m_awaitingResponse && System.currentTimeMillis() > m_lastTime + CONNECTION_TIMEOUT;
	}
	
	// get the time from the last response received from the user in the form MM:SS
	public String getLastResponseTimeInSecondsAsString() {
		long time = m_awaitingResponse ? System.currentTimeMillis() - m_lastTime : 0;
		long minutes = TimeUnit.MILLISECONDS.toMinutes(time);
		long seconds = TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time));
		return String.format(((minutes < 10) ? "0" : "") + "%d:" + ((minutes < 10) ? "0" : "") + "%d", minutes, seconds);
	}
	
	// convert the user's information to a String array
	public String[] getAsTableEntry() {
		return new String[] { m_queueName, m_userName, getLastResponseTimeInSecondsAsString() };
	}
	
	// check if one user is equal to another
	public boolean equals(Object o) {
		if(o == null || !(o instanceof User)) { return false; }
		return ((User) o).m_queueName.equals(m_queueName);
	}
	
	// convert the user to a string
	public String toString() {
		return m_queueName + " " + m_userName;
	}
	
}
