/*
 * Created on 03.06.2004
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 */
package networkconsole.tests;

import java.io.FileInputStream;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Properties;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;

import junit.framework.TestCase;
import networkconsole.datamodel.Entry;
import networkconsole.datamodel.EntryList;
import networkconsole.datamodel.EntryListException;
import networkconsole.datamodel.IEntryListAdapter;
import networkconsole.datamodel.JdbcEntryList;
import networkconsole.datamodel.LdapEntryList;
import networkconsole.datamodel.LdapEntryReflector;
import networkconsole.datamodel.LdapHostEntry;
import networkconsole.datamodel.LdapHostEntryList;
import networkconsole.datamodel.LdapUserEntry;
import networkconsole.datamodel.LdapUserEntryList;
import networkconsole.datamodel.sax.JdbcEntryListInputSource;
import networkconsole.datamodel.sax.JdbcEntryListXMLReader;
import networkconsole.datamodel.sax.LdapEntryListInputSource;
import networkconsole.datamodel.sax.LdapEntryListXMLReader;

/**
 * Apply correct data on ldap server if needed: 
 * ldapadd -x -D "cn=manager,dc=ewsd,dc=donpac,dc=ru" -w "secret" -f testdata.ldif 
 * 
 * @author Eugene Prokopiev <eugene_prokopiev@mail.ru>
 * 
 */
public class Testing extends TestCase {
	
	Properties properties = new Properties();

	public Testing(String arg0) {
		super(arg0);
	}

	public static void main(String[] args) {
		junit.textui.TestRunner.run(Testing.class);
	}

	protected void setUp() throws Exception {
		properties.load(new FileInputStream("networkconsole.properties"));	
		super.setUp();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}
	
	public void testLdapUserEntryList() throws EntryListException {		
		
		System.out.println("create EntryList: LdapUserEntryList");
		EntryList list = new LdapUserEntryList(
			properties.getProperty("connection.ldap.url"),
			properties.getProperty("connection.ldap.context.users"),
			properties.getProperty("connection.ldap.user"),
			properties.getProperty("connection.ldap.password"));
			
		System.out.println("add change listener for EntryList: "+list.getClass().getName());
		list.addChangeListener(new IEntryListAdapter() {
			public void entryAdd(Entry entry) throws EntryListException {
				System.out.println("entryAdd: "+entry);
			}
			public void entryEdit(Entry entry) throws EntryListException {
				System.out.println("entryEdit: "+entry);
			}
			public void entryRemove(Entry entry) throws EntryListException {
				System.out.println("entryRemove: "+entry);
			}
			public void refresh() throws EntryListException {
				System.out.println("refresh");
			}
		});
					
		printEntryList(list);
		
		System.out.println("change entry for EntryList: "+list.getClass().getName());
		LdapUserEntry user1 = (LdapUserEntry)list.getEntries().get(0);
		user1.setFullName("LDAP User 1");	
		
		printEntryList(list);	
		
		System.out.println("add entry for EntryList: "+list.getClass().getName());
		LdapUserEntry user2 = new LdapUserEntry("ldapuser2");
		user2.setUid("1002");
		user2.setGid("10");
		user2.setFullName("LDAP User 2");
		user2.setShell("/bin/bash");
		user2.setHome("/home/ldapuser2");
		list.add(user2);	
		
		printEntryList(list);
		
		System.out.println("remove entry for EntryList: "+list.getClass().getName());
		LdapUserEntry user3 = new LdapUserEntry("ldapuser2");
		list.remove(user3);	
		
		printEntryList(list);
		
		list.dispose();
	}
	
	public void testLdapHostEntryList() throws EntryListException {		
		
		System.out.println("create EntryList: LdapHostEntryList");
		EntryList list = new LdapHostEntryList(
			properties.getProperty("connection.ldap.url"),
			properties.getProperty("connection.ldap.context.hosts"),
			properties.getProperty("connection.ldap.user"),
			properties.getProperty("connection.ldap.password"));
			
		System.out.println("add change listener for EntryList: "+list.getClass().getName());
		list.addChangeListener(new IEntryListAdapter() {
			public void entryAdd(Entry entry) throws EntryListException {
				System.out.println("entryAdd: "+entry);
			}
			public void entryEdit(Entry entry) throws EntryListException {
				System.out.println("entryEdit: "+entry);
			}
			public void entryRemove(Entry entry) throws EntryListException {
				System.out.println("entryRemove: "+entry);
			}
			public void refresh() throws EntryListException {
				System.out.println("refresh");
			}
		});
					
		printEntryList(list);
		
		System.out.println("change entry for EntryList: "+list.getClass().getName());
		LdapHostEntry host1 = (LdapHostEntry)list.getEntries().get(0);
		host1.setDhcpHWAddress("00:00:00:00:00:00");	
		
		printEntryList(list);	
	
		System.out.println("add entry for EntryList: "+list.getClass().getName());
		LdapHostEntry host2 = new LdapHostEntry("host2");
		host2.setDhcpHWAddress("00:00:00:00:00:00");
		host2.setDhcpIPAddress("192.168.101.1");
		host2.setAllowNat(new Boolean(true));
		host2.setAllowProxy(new Boolean(true));
		host2.setForceProxy(new Boolean(true));
		list.add(host2);	
		
		printEntryList(list);
	
		System.out.println("remove entry for EntryList: "+list.getClass().getName());
		LdapHostEntry host3 = new LdapHostEntry("host2");
		list.remove(host3);	
		
		printEntryList(list);
					
		list.dispose();
	}
	
	public void testJdbcEntryList() throws EntryListException, SQLException, ClassNotFoundException {	
		
		System.out.println("create JDBC connection");
		Class.forName("org.firebirdsql.jdbc.FBDriver");
		Connection connection = DriverManager.getConnection(
			properties.getProperty("connection.jdbc.url"),
			properties.getProperty("connection.jdbc.user"),
			properties.getProperty("connection.jdbc.password"));	
		
		System.out.println("create EntryList: JdbcEntryList");
		JdbcEntryList list = new JdbcEntryList(connection, "", 
			properties.getProperty("ui.view.traffic.translate").equals("true"));
		list.setSql("select first 3 * from proxy_log");
		
		printEntryList(list);
					
		list.dispose();
	}
	
	public void testReflectionEntryList() throws EntryListException {
		
		System.out.println("create EntryList: LdapUserEntryList");
		LdapEntryList list1 = new LdapUserEntryList(
			properties.getProperty("connection.ldap.url"),
			properties.getProperty("connection.ldap.context.users"),
			properties.getProperty("connection.ldap.user"),
			properties.getProperty("connection.ldap.password"));
		printReflectedFields(list1.getEntryClass());
		
		System.out.println("create EntryList: LdapHostEntryList");
		LdapEntryList list2 = new LdapHostEntryList(
			properties.getProperty("connection.ldap.url"),
			properties.getProperty("connection.ldap.context.hosts"),
			properties.getProperty("connection.ldap.user"),
			properties.getProperty("connection.ldap.password"));
		printReflectedFields(list2.getEntryClass());
	}
	
	public void testSaxJdbcEntryList()  
		throws EntryListException, 
		SQLException, 
		ClassNotFoundException, 
		TransformerConfigurationException, 
		TransformerException {
		
		System.out.println("create JDBC connection");
		Class.forName("org.firebirdsql.jdbc.FBDriver");
		Connection connection = DriverManager.getConnection(
			properties.getProperty("connection.jdbc.url"),
			properties.getProperty("connection.jdbc.user"),
			properties.getProperty("connection.jdbc.password"));	
		
		System.out.println("create EntryList: JdbcEntryList");
		JdbcEntryList list = new JdbcEntryList(connection, "", 
			properties.getProperty("ui.view.traffic.translate").equals("true"));
		list.setSql("select first 3 * from proxy_log");
		
		SAXSource source = new SAXSource(
			new JdbcEntryListXMLReader(), 
			new JdbcEntryListInputSource(list.getClass().getName(), list));
		
		StringWriter xmlresult = new StringWriter();			
		TransformerFactory factory = TransformerFactory.newInstance();			
		Transformer transformer = factory.newTransformer();	
		transformer.setOutputProperty(OutputKeys.ENCODING, "cp1251");			
		transformer.transform(source, new StreamResult(xmlresult));
		System.out.println(xmlresult);
					
		list.dispose();
	}
	
	public void testSaxLdapEntryList() 
		throws EntryListException, 
		ClassNotFoundException, 
		TransformerConfigurationException, 
		TransformerException {
		
		System.out.println("create EntryList: LdapHostEntryList");
		LdapEntryList list = new LdapHostEntryList(
			properties.getProperty("connection.ldap.url"),
			properties.getProperty("connection.ldap.context.hosts"),
			properties.getProperty("connection.ldap.user"),
			properties.getProperty("connection.ldap.password"));
			
		SAXSource source = new SAXSource(
			new LdapEntryListXMLReader(), 
			new LdapEntryListInputSource(list.getClass().getName(), list));
		
		StringWriter xmlresult = new StringWriter();			
		TransformerFactory factory = TransformerFactory.newInstance();			
		Transformer transformer = factory.newTransformer();	
		transformer.setOutputProperty(OutputKeys.ENCODING, "cp1251");			
		transformer.transform(source, new StreamResult(xmlresult));
		System.out.println(xmlresult);
					
		list.dispose();
	}

	private void printEntryList(EntryList list) {
		
		System.out.println("print EntryList: "+list.getClass().getName());
		
		Iterator i = list.getEntries().iterator();
		while(i.hasNext()){
			System.out.println(i.next());
		}
	}
	
	private void printReflectedFields(Class entryClass) {
		
		System.out.println("print reflected fields LdapEntryList: "+entryClass.getName());
		
		LdapEntryReflector reflector = new LdapEntryReflector(entryClass);
		
		System.out.println("describe methods:");
		printMethods(reflector.getDescribeMethods().iterator());
		
		System.out.println("getter methods:");
		printMethods(reflector.getGetterMethods().iterator());
		
		System.out.println("setter methods:");
		printMethods(reflector.getSetterMethods().iterator());
	}

	private void printMethods(Iterator i) {
		while (i.hasNext()) {	
			Object o = i.next();
			if (o != null)
				System.out.println("\t"+o.toString());
		}
	}
	
}
