package hiro.yoshioka.sql.notes.reflect;

import hiro.yoshioka.classmanager.ClassManager;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;

public class WolfDatabase extends AbsWolfDominoReflection {
	Method createNoteCollection;
	Method createDocument;
	Method getAllDocuments;
	Method getDocumentByUNID;
	Method getCategories;
	Method getTitle;
	Method getFilePath;
	Method getTemplateName;
	Method getURL;
	Method getCurrentAccessLevel;
	Method getFileName;
	Method getServer;
	Method getACL;
	Method getForms;
	Method getView;
	Method getViews;
	Method isOpen;
	Method open;
	Method search;
	Method search3;

	public WolfDatabase(ClassManager classManager, Object targetInstance)
			throws MalformedURLException, ClassNotFoundException,
			SecurityException, NoSuchMethodException {
		super(classManager, targetInstance);

		getAllDocuments = targetInstance.getClass()
				.getMethod("getAllDocuments");
		getCategories = targetInstance.getClass().getMethod("getCategories");
		createDocument = targetInstance.getClass().getMethod("createDocument");
		getDocumentByUNID = targetInstance.getClass().getMethod(
				"getDocumentByUNID", String.class);
		getTitle = targetInstance.getClass().getMethod("getTitle");
		getFilePath = targetInstance.getClass().getMethod("getFilePath");
		getTemplateName = targetInstance.getClass()
				.getMethod("getTemplateName");
		getURL = targetInstance.getClass().getMethod("getURL");
		getFileName = targetInstance.getClass().getMethod("getFileName");
		getServer = targetInstance.getClass().getMethod("getServer");

		getACL = targetInstance.getClass().getMethod("getACL");
		getForms = targetInstance.getClass().getMethod("getForms");
		getView = targetInstance.getClass().getMethod("getView", String.class);
		getViews = targetInstance.getClass().getMethod("getViews");

		getCurrentAccessLevel = targetInstance.getClass().getMethod(
				"getCurrentAccessLevel");
		open = targetInstance.getClass().getMethod("open");
		isOpen = targetInstance.getClass().getMethod("isOpen");
		createNoteCollection = targetInstance.getClass().getMethod(
				"createNoteCollection", boolean.class);

		search = targetInstance.getClass().getMethod("search", String.class);
		Class datetime = classManager.getClassForName("lotus.domino.DateTime");
		try {
			search3 = targetInstance.getClass().getMethod("search",
					String.class, datetime, int.class);
		} catch (NoSuchMethodException e) {
			for (Method m : targetInstance.getClass().getMethods()) {
				if (m.toString().indexOf(
						".search(java.lang.String,lotus.domino.DateTime,int)") >= 0) {
					search3 = m;
					break;
				}
			}
		}
	}

	@Override
	public String getDominoClassName() {
		return "lotus.domino.Database";
	}

	public List<WolfForm> getForms() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException,
			MalformedURLException, SecurityException, ClassNotFoundException,
			NoSuchMethodException {
		Vector o = (Vector) getForms.invoke(targetInstance);
		if (o == null) {
			return Collections.EMPTY_LIST;
		}
		List<WolfForm> retList = new ArrayList<WolfForm>();
		for (Object instance : o) {
			WolfForm document = new WolfForm(classManager, instance);
			retList.add(document);
		}
		return retList;
	}

	public WolfView getView(String name) throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException,
			MalformedURLException, SecurityException, ClassNotFoundException,
			NoSuchMethodException {
		Object instance = getView.invoke(targetInstance, name);
		if (instance == null) {
			return null;
		}

		return new WolfView(classManager, instance);
	}

	public WolfDocument getDocumentByUNID(String unid)
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, MalformedURLException,
			SecurityException, ClassNotFoundException, NoSuchMethodException {

		Object instance = getDocumentByUNID.invoke(targetInstance, unid);
		if (instance == null) {
			return null;
		}

		return new WolfDocument(classManager, instance);
	}

	public WolfDocumentCollection search(String queryString)
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, MalformedURLException,
			SecurityException, ClassNotFoundException, NoSuchMethodException {
		Object instance = search.invoke(targetInstance, queryString);
		if (instance == null) {
			return null;
		}

		return new WolfDocumentCollection(classManager, instance);
	}

	public WolfDocumentCollection search(String queryString, int maxCount)
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, MalformedURLException,
			SecurityException, ClassNotFoundException, NoSuchMethodException {

		Object instance = search3.invoke(targetInstance, queryString, null,
				maxCount);
		if (instance == null) {
			return null;
		}

		return new WolfDocumentCollection(classManager, instance);
	}

	public List<WolfView> getViews() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException,
			MalformedURLException, SecurityException, ClassNotFoundException,
			NoSuchMethodException {
		Vector o = (Vector) getViews.invoke(targetInstance);
		if (o == null) {
			return Collections.EMPTY_LIST;
		}
		List<WolfView> retList = new ArrayList<WolfView>();
		for (Object instance : o) {
			WolfView document = new WolfView(classManager, instance);
			retList.add(document);
		}
		return retList;
	}

	public List<WolfDocument> getAllDocuments()
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, MalformedURLException,
			SecurityException, ClassNotFoundException, NoSuchMethodException {
		Vector o = (Vector) getAllDocuments.invoke(targetInstance);
		if (o == null) {
			return Collections.EMPTY_LIST;
		}
		List<WolfDocument> retList = new ArrayList<WolfDocument>();
		for (Object instance : o) {
			WolfDocument document = new WolfDocument(classManager, instance);
			retList.add(document);
		}
		return retList;
	}

	public WolfACL getACL() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException,
			MalformedURLException, SecurityException, ClassNotFoundException,
			NoSuchMethodException {
		Object instance = getACL.invoke(targetInstance);
		if (instance == null) {
			return null;
		}

		return new WolfACL(classManager, instance);
	}

	public String getCategories() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (String) getCategories.invoke(targetInstance);
	}

	public String getTitle() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (String) getTitle.invoke(targetInstance);
	}

	public String getFilePath() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (String) getFilePath.invoke(targetInstance);
	}

	public String getTemplateName() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (String) getTemplateName.invoke(targetInstance);
	}

	public String getURL() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (String) getURL.invoke(targetInstance);
	}

	public String getFileName() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (String) getFileName.invoke(targetInstance);
	}

	public String getServer() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (String) getServer.invoke(targetInstance);
	}

	public int getCurrentAccessLevel() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (Integer) getCurrentAccessLevel.invoke(targetInstance);
	}

	public void open() throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException {
		open.invoke(targetInstance);
	}

	public boolean isOpen() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		return (Boolean) isOpen.invoke(targetInstance);
	}

	public WolfDocument createDocument() throws IllegalArgumentException,
			IllegalAccessException, InvocationTargetException,
			MalformedURLException, SecurityException, ClassNotFoundException,
			NoSuchMethodException {
		Object instance = createDocument.invoke(targetInstance);
		if (instance == null) {
			return null;
		}
		return new WolfDocument(classManager, instance);
	}

	public WolfNoteCollection createNoteCollection(boolean b)
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, MalformedURLException,
			SecurityException, ClassNotFoundException, NoSuchMethodException {
		Object instance = createNoteCollection.invoke(targetInstance, b);
		if (instance == null) {
			return null;
		}
		return new WolfNoteCollection(classManager, instance);
	}

	@Override
	public String toString() {
		StringBuilder buf = new StringBuilder();
		try {
			buf.append(String.format("WolfDocument %s [%s]%n", getTitle(),
					getFileName()));

			for (WolfForm form : getForms()) {
				buf.append("  " + form);
				form.recycle();
			}
			for (WolfView view : getViews()) {
				buf.append("  " + view);
				view.recycle();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return buf.toString();
	}

}
