package net.sourceforge.fenixedu.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.StringTokenizer;

import net.sourceforge.fenixedu.domain.Login;
import net.sourceforge.fenixedu.domain.LoginAlias;
import net.sourceforge.fenixedu.domain.Person;
import net.sourceforge.fenixedu.domain.Role;
import net.sourceforge.fenixedu.domain.degree.DegreeType;
import net.sourceforge.fenixedu.domain.exceptions.DomainException;
import net.sourceforge.fenixedu.domain.person.IDDocumentType;
import net.sourceforge.fenixedu.domain.person.RoleType;
import net.sourceforge.fenixedu.domain.student.Registration;
//import net.sourceforge.fenixedu.domain.student.StudentType;

import org.apache.commons.lang.StringUtils;

public class UsernameUtilsIscte extends FenixUtil {

    public static boolean shouldHaveUID(Person person) {
	Login loginIdentification = person.getLoginIdentification();
	if (loginIdentification != null) {
	    return person.hasRole(RoleType.TEACHER) || person.hasRole(RoleType.EMPLOYEE)
		    || person.hasRole(RoleType.STUDENT) || person.hasRole(RoleType.GRANT_OWNER);
	}
	return false;
    }
    
    private static String getEmployeeLogin(Person person)
    {
	String name = StringFormatter.normalize(person.getName());
	name = name.toLowerCase();
	name = name.replaceAll(" de ", " ");
	name = name.replaceAll(" da ", " ");
	name = name.replaceAll(" dos ", " ");
	name = name.replaceAll(" das ", " ");
	name = name.replaceAll(" e ", " ");
	StringTokenizer strTok = new StringTokenizer(name);
	
	ArrayList<String> names = new ArrayList<String>();	
	
	while(strTok.hasMoreTokens())
	{
	    names.add(strTok.nextToken());
	}
	
	int numNames = names.size();	

	String login = "";
	String lastName;
	int diffChars;
	int numChars;	
	
	numNames = names.size();	
	
	if(numNames >= 5)
	{
	    login = login +names.get(0).charAt(0) + names.get(1).charAt(0) + names.get(2).charAt(0) + names.get(numNames - 2).charAt(0) + names.get(numNames - 1).charAt(0);		    
	}
	else
	{
	    for(int i = 0 ; i < numNames ; i++)
	    {
		login += names.get(i).charAt(0);			
	    }
	    
	    diffChars = 5 - numNames;
	    
	    for(int i = 0 ; i < diffChars ; i++)
	    {
		lastName = names.get(numNames -1);
		numChars = lastName.length();
		login += lastName.charAt(numChars - diffChars + i);
	    }
	}	
	Person p = Person.readByDocumentIdNumberAndIdDocumentType("ad",IDDocumentType.IDENTITY_CARD);
	
	if(LoginAlias.checkIfAlreadyExists(login, person))
	{
	    //If the login already exists - the employee login will be f[employee_number]@iscte.pt
	    login = "f" + person.getEmployee().getEmployeeNumber();	    
	}
	
	return login;
    }

    public static String updateIstUsername(Person person) {

	String currentUsername = person.getIstUsername();
	if (currentUsername == null && shouldHaveUID(person)) {

	    String username = null;

	    Role mostImportantRole = getMostImportantRole(person.getPersonRoles());
	    RoleType mostImportantRoleType = mostImportantRole.getRoleType();
	    
	    if (mostImportantRoleType == RoleType.TEACHER || mostImportantRoleType == RoleType.EMPLOYEE || (mostImportantRoleType == RoleType.GRANT_OWNER && person.getGrantOwner() != null)) {
		
		username = getEmployeeLogin(person);		
	   
	    } else if (mostImportantRole.getRoleType() == RoleType.STUDENT
		    && person.getStudentByType(DegreeType.MASTER_DEGREE) != null) {
		final Integer number = person.getStudentByType(DegreeType.MASTER_DEGREE).getNumber();
		
		username = "m" + number;

	    } else if (mostImportantRole.getRoleType() == RoleType.STUDENT
		    && person.getStudentByType(DegreeType.BOLONHA_ADVANCED_FORMATION_DIPLOMA) != null) {
		final Integer number = person.getStudentByType(DegreeType.BOLONHA_ADVANCED_FORMATION_DIPLOMA).getNumber();

		username = "p" + number;
		
	    } else if (mostImportantRole.getRoleType() == RoleType.STUDENT
		    && person.getStudentByType(DegreeType.BOLONHA_PHD_PROGRAM) != null) {
		final Integer number = person.getStudentByType(DegreeType.BOLONHA_PHD_PROGRAM).getNumber();

		username = "d" + number;
		 

	    } else if (mostImportantRole.getRoleType() == RoleType.STUDENT) {
		Registration registration = person.getStudentByType(DegreeType.DEGREE);
		if (registration == null) {
		    registration = person.getStudentByType(DegreeType.BOLONHA_DEGREE);
		}
		if (registration == null) {
		    registration = person.getStudentByType(DegreeType.BOLONHA_MASTER_DEGREE);		    
		}
		if (registration == null) {
		    registration = person.getStudentByType(DegreeType.BOLONHA_INTEGRATED_MASTER_DEGREE);
		}
		if (registration != null) {
		    if (registration.getRegistrationAgreement().isNormal()) {
			username = "a" + registration.getNumber();
		    }
		    else
		    {
			username = "e" + registration.getNumber();
		    }		   
		} else if (person.hasStudent()) {

		    username = "a" + person.getStudent().getNumber();
		}
	    }

	    if (StringUtils.isEmpty(username)) {
		throw new DomainException("error.setting.istUsername.not.authorized");
	    }

	    
	    return username + "@iscte.pt";
	}

	return currentUsername;
    }

    public static String generateNewUsername(RoleType roleType, Person person) {

	
	if (roleType.equals(RoleType.TEACHER)) {
	    if (person.getTeacher() != null) {
		return getEmployeeLogin(person) + "@iscte.pt";
	    } else {
		throw new DomainException("error.person.addingInvalidRole", RoleType.TEACHER.getName());
	    }

	} else if (roleType.equals(RoleType.EMPLOYEE)) {
	    if (person.getEmployee() != null) {
		return getEmployeeLogin(person) + "@iscte.pt";
	    } else {
		throw new DomainException("error.person.addingInvalidRole", RoleType.EMPLOYEE.getName());
	    }

	} else if (roleType.equals(RoleType.STUDENT)) {

	    Registration registration = person
		    .getStudentByType(DegreeType.BOLONHA_ADVANCED_FORMATION_DIPLOMA);
	    if (registration != null) {
		
		if (registration.getRegistrationAgreement().isNormal()) {
		    return "a" + registration.getNumber() + "@iscte.pt";
		} else {
		    return "e" + registration.getNumber() + "@iscte.pt"; 
		}
	    }

	    registration = person.getStudentByType(DegreeType.MASTER_DEGREE);
	    if (registration != null) {
		
		if (registration.getRegistrationAgreement().isNormal()) {
		    return "a" + registration.getNumber() + "@iscte.pt";
		} else {
		    return "e" + registration.getNumber() + "@iscte.pt"; 
		}
	    }

	    registration = person.getStudentByType(DegreeType.DEGREE);
	    if (registration != null) {
		
		if (registration.getRegistrationAgreement().isNormal()) {
		    return "a" + registration.getNumber() + "@iscte.pt";
		} else {
		    return "e" + registration.getNumber() + "@iscte.pt"; 
		}
	    }

	    registration = person.getStudentByType(DegreeType.BOLONHA_DEGREE);
	    if (registration != null) {
		if (registration.getRegistrationAgreement().isNormal()) {
		    return "a" + registration.getNumber() + "@iscte.pt";
		} else {
		    return "e" + registration.getNumber() + "@iscte.pt"; 
		}
	    }

	    registration = person.getStudentByType(DegreeType.BOLONHA_INTEGRATED_MASTER_DEGREE);
	    if (registration != null) {
		if (registration.getRegistrationAgreement().isNormal()) {
		    return "a" + registration.getNumber() + "@iscte.pt";
		} else {
		    return "e" + registration.getNumber() + "@iscte.pt"; 
		}
	    }

	    if (person.hasStudent()) {// phd...
		return "a" + person.getStudent().getNumber() + "@iscte.pt";
	    }

	    throw new DomainException("error.person.addingInvalidRole", RoleType.STUDENT.getName());

	} else if (roleType.equals(RoleType.GRANT_OWNER)) {
	    if (person.getGrantOwner() != null) {
		return getEmployeeLogin(person) + "@iscte.pt";
	    }

	} else if (roleType.equals(RoleType.PROJECTS_MANAGER)
		|| roleType.equals(RoleType.INSTITUCIONAL_PROJECTS_MANAGER)) {
	    return getEmployeeLogin(person) + "@iscte.pt";

	} else if (roleType.equals(RoleType.ALUMNI)) {
	    Registration registration = person.getStudentByType(DegreeType.DEGREE);
	    if (registration != null) {
		return "a" + registration.getNumber() + "@iscte.pt";
	    }
	    // throw new DomainException("error.person.addingInvalidRole",
	    // RoleType.ALUMNI.getName());
	    return null;

	}/* else if (roleType.equals(RoleType.MASTER_DEGREE_CANDIDATE)
		|| roleType.equals(RoleType.CANDIDATE)) {
	    return "C" + person.getIdInternal();

	} else if (roleType.equals(RoleType.PERSON)) {
	    return "P" + person.getIdInternal();
	}*/

	return null;
    }

    public static Role getMostImportantRole(Collection<Role> roles) {
	for (RoleType roleType : RoleType.getRolesImportance()) {
	    for (Role role : roles) {
		if (role.getRoleType().equals(roleType)) {
		    return role;
		}
	    }
	}
	return null;
    }    
}
