import java.io.*;
import java.util.*;
import com.novell.ldap.*;

public class ChangeManager {

	public StringBuffer errString = new StringBuffer();
	LDAPConnection c;
	ConnectionMaker cm;
	
	public ChangeManager () {
			cm = new Cippie();
			errString.append (cm.showErrors());
			c = cm.getConnection();
			if (cm.hasError()) {
				errString.append (cm.showErrors());
				System.out.println(cm.showErrors ());
			}
	}

	public List getChildren (String dn, String [] attrs) {
		try {
			LDAPSearchResults res=c.search(dn, LDAPConnection.SCOPE_ONE,null,null,false);
			List l = new ArrayList();
			while (res.hasMore()) 
				l.add (getAttrs(res.next().getDN(), attrs));
			return l;
		} catch (LDAPException e) {
			handleLDAPException (e, "");
			return new ArrayList();
		}
	}
	HashMap getAttrs (String dn, String [] attrs) {
		try {
			LDAPEntry entry = c.read( dn, attrs );
			LDAPAttributeSet attributeSet = entry.getAttributeSet();
			Iterator it = attributeSet.iterator();
			LDAPAttribute attribute;
			HashMap h = new HashMap();
			while(it.hasNext()) {
				attribute = (LDAPAttribute)it.next();
				h.put (attribute.getName(),Collections.list(attribute.getStringValues()));
			}
			return h;
		} catch (LDAPException e) {
			handleLDAPException (e, "");
			return new HashMap();
		}
	}	
	
	public List getCourseList (String term) {
		return getChildren (cm.getCourseContext(term), new String [] 
				{"cn", "description", "l" });
	}
				
	public HashMap getCourseDetails (String term, String course) {
		return getAttrs (courseDN(term, course), new String [] 
				{"cn", "description", "l" });
	}

	public List getCourseStudents (String term, String course) {
		return getCourseStudents (term, course, 0);
	}
	
	public List getCourseStudents (String term, String course, int teststud) {
		HashMap h = getAttrs (courseDN(term, course), new String []
				{"uniqueMember"});
		if (h.containsKey (new String ("uniqueMember"))) {
		    List l = (ArrayList)h.get(new String ("uniqueMember"));
			if (teststud == 1) { //return list as is
				return l;
			} else { //purge teststud from list, default
				if (l.contains (new String
						("cn=teststud,ou=Studenten,ou=Vetmed,o=uni-muenchen"))) {
					int index = l.indexOf (new String("cn=teststud,ou=Studenten,ou=Vetmed,o=uni-muenchen"));
					l.remove (index);
				}
				return l;
			}
		} else {
			return new ArrayList();
		}
	}
	
	public boolean isRegistered (String term, String subject, String observer) {
		List l = getCourseStudents (term, subject,1);
		ListIterator li = l.listIterator();
		String newobserver = "cn=" + observer + ",ou=Studenten,ou=Vetmed,o=uni-muenchen";
		String name;
		while (li.hasNext()) {
			name = (String)li.next();
			if (name != null && (0 == name.compareToIgnoreCase (newobserver))) return true;
		}
		return false;								
	}
	
	public boolean isOpen (String term, String subject) {

     	HashMap h = getAttrs (courseDN(term, subject), new String []
			                 {"l"});
	    List l = (ArrayList)h.get(new String ("l"));
		
		//return true; /*KLUDGE, outcomment for allowing registration*/
		int act = getCourseStudents (term, subject).size();
		int cap = Integer.parseInt((String)l.get(0));
		if (cap > act) return true;
		else return false;
	}	
	
	private void mark (String action, String term, String subject, String observer) {
		Date dt = new Date();
		System.out.println ("MARK:" + dt + " " + action + " " + term + "/" + subject + " " + observer);
	}
	
	public boolean register (String term, String subject, String observer) {
		try {
			LDAPAttribute attr = new LDAPAttribute ("uniqueMember", studentDN (observer));
		 	c.modify (courseDN (term, subject), 
					new LDAPModification (LDAPModification.ADD, attr));
			mark ("register success", term, subject, observer); 
		 	return true;
		}	catch (LDAPException e) {
			mark ("register failure", term, subject, observer); 
			handleLDAPException (e, "");
			return false;
		}
	}

	public void addCourse (String name, String longname, String description, String maxno, String term) {
		try {
			LDAPAttributeSet attrSet = new LDAPAttributeSet();
			String[] attrValues = {"groupOfNames", "top"};
			attrSet.add (new LDAPAttribute ("objectClass", attrValues));
			String [] attrValues2 = {name, longname};
			attrSet.add (new LDAPAttribute ("cn", attrValues2));
			attrSet.add (new LDAPAttribute ("description", description));
			attrSet.add (new LDAPAttribute ("l", maxno));
			attrSet.add (new LDAPAttribute ("ou", term));
			attrSet.add (new LDAPAttribute ("ACL", "2#entry#[Root]#uniqueMember"));
			c.add (new LDAPEntry (courseDN (term, name), attrSet));
		}	catch (LDAPException e) {
			handleLDAPException (e, "");
		}
	}
	
	public void delCourse (String name, String term) {
		try {
			c.delete (courseDN (term, name));
		}	catch (LDAPException e) {
			handleLDAPException (e, "");
		}
	}
	
	public boolean unregister (String term, String subject, String observer) {
		try {	
			LDAPAttribute attr = new LDAPAttribute ("uniqueMember", studentDN (observer));
			c.modify (courseDN(term, subject),
				new LDAPModification (LDAPModification.DELETE, attr));
			mark ("unregister success", term, subject, observer); 
			return true;
		} catch (LDAPException e) {
			mark ("unregister failure", term, subject, observer); 
			handleLDAPException (e, "");
			return false;
		}
	}

	public boolean checkPassword (String observer, String password) {
		try {
			LDAPAttribute attr = new LDAPAttribute("userPassword", password );
			return c.compare (studentDN(observer), attr);
		} catch (LDAPException e) {
			handleLDAPException (e, "Invalid credentials: ");
			return false;
		}
	}

	public void disconnect () {
		try {
			c.disconnect();
		} catch (LDAPException e) {
			handleLDAPException (e, "");
		}
	}
	
	String studentDN (String student) {
		return "cn=" + student + ", " + cm.getStudentContext();
	}
		
	String courseDN (String term, String subject) {
		return "cn=" + subject + ", " + cm.getCourseContext(term);
	}
	
	public String getURL () {
		return "index.html";
	}

	public String getMethod () {
		return "post";
	}
	
	public void handleLDAPException (LDAPException e, String comment) {
		errString.append (comment);
		errString.append (e.getLDAPErrorMessage());
		errString.append (e);
		System.out.println (comment);
		System.out.println (e.getLDAPErrorMessage());
		e.printStackTrace();
		/*try {
			Mail m = new Mail();
			m.sendMsg (comment + "\n" + e + "\n" + e.getLDAPErrorMessage());
		} catch (Exception ex) {
			errString.append ("Unable to send sysop errstring mail");
			ex.printStackTrace();
		}*/
	}
		
	public String showErrors () {
		if (errString.length() == 0) return "";
		else return "<blockquote>" + new String (errString) + " Fehler! Bitte senden Sie eine "
			+ " Email an webmaster@vetmed.uni-muenchen.de. Es waere gut wenn Sie "
			+ " den gesamten in Ihrem Browser angezeigten Text hineinpasten. Danke!"
			+ "</blockquote>";
	}
		
}
