package dynamic.people;

import dynamic.common.LoginHandler;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import java.util.HashMap;

public class AddressBookRetriever {

    static HashMap<String,AddressBookEntry> entries = new HashMap<String, AddressBookEntry>();

    public static void main(String[] args) {
        if(args.length != 1)
            System.out.println("ERROR: please supply a college login to search");
        else{
            AddressBookEntry abe = GetAddressBookDetails(args[0].trim());
            System.out.println(abe);
            if(abe != null)
                System.out.println(abe.displayname);
        }
    }

    static boolean REPORT_LDAP_TIMEOUTS = true;
    static int LDAP_MAX_ATTEMPTS = 2;

    static DirContext ctx = null;
    static String address = "addressbook.imperial.ac.uk";
    static String base = "o=Imperial College,c=GB";
    //    static String address = "unixldap4.cc.ic.ac.uk";
//    static String base = "ou=shibboleth,dc=ic,dc=ac,dc=uk";
    static int port = 389;

    public static AddressBookEntry GetAddressBookDetails(String uid) {

        if(entries.containsKey(uid))
            return entries.get(uid);

        try {

            if (ctx == null)
                ctx = new InitialDirContext();

            SearchControls ctls = new SearchControls();
//            ctls.setTimeLimit(10000);
            ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

            int attempts = 0;
            NamingEnumeration answer = null;
            while((answer == null || !answer.hasMoreElements()) && ++attempts < LDAP_MAX_ATTEMPTS)
                answer = ctx.search("ldap://" + address + ":" + port + "/" + base, "(uid=" + uid + ")", ctls);
            if(REPORT_LDAP_TIMEOUTS && attempts == LDAP_MAX_ATTEMPTS)
                System.out.println("LDAP timeout retreiving information for " + uid);

            if(!answer.hasMoreElements()) return null;

            SearchResult res = (SearchResult) answer.nextElement();
            Attributes a = res.getAttributes();

            AddressBookEntry abe = new AddressBookEntry();

            abe.givenname = GetResponseValue(a, "givenname");
            abe.title = GetResponseValue(a, "title");
            abe.physicaldeliveryofficename = GetResponseValue(a, "physicaldeliveryofficename");
            abe.roomnumber = GetResponseValue(a, "roomnumber");
            abe.displayname = GetResponseValue(a, "displayname");
            abe.surname = GetResponseValue(a, "sn");
            abe.l = GetResponseValue(a, "l");
            abe.mail = GetResponseValue(a, "mail");
            abe.uid = GetResponseValue(a, "uid");
            abe.employeetype = GetResponseValue(a, "employeetype");
            abe.other = GetResponseValue(a, "o");
            abe.telephone = GetResponseValue(a, "telephonenumber");

            abe.room = DetermineRoomString(abe);

            entries.put(uid,abe);
            return abe;

        } catch (NamingException e) {
            System.out.println("Error accessing LDAP - remote access needs VPN login");
            System.exit(0);
        }

        return null;

    }

    private static String DetermineRoomString(AddressBookEntry abe) {

        String room = "Huxley";

        if(abe.l.indexOf("Penney") >=0)
            room = "William Penney";

        if(abe.l.indexOf("Bessemer") >=0)
            room = "Bessemer";

        room += " " + abe.roomnumber;

        room = room.replaceAll("Department of Computing","");
        room = room.trim();
        if(room.endsWith(","))
            room = room.substring(0,room.length()-1);

        return room;

    }

    private static String GetResponseValue(Attributes a, String attname) throws NamingException {

        Attribute o = a.get(attname);
        if(o == null)
            return "";
        return String.valueOf(o.get());

    }

}