package de.ugoe.cs.swe.memos.tests.database;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.sql.SQLException;
import java.util.Iterator;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import de.ugoe.cs.swe.memos.database.Connector;
import de.ugoe.cs.swe.memos.database.DBUtility;
import de.ugoe.cs.swe.memos.database.DatabaseException;
import de.ugoe.cs.swe.memos.datamodel.Category;
import de.ugoe.cs.swe.memos.datamodel.File;
import de.ugoe.cs.swe.memos.datamodel.Memo;

public class DatabaseConnectorTest {

	private DBUtility dBAccess;

	@Before
	public void up() {
		this.dBAccess = DBUtility.getInstance();

	}

	@After
	public void down() {
		try {
			Connector.closeConnection();
		} catch (Exception e) {
		}
	}

	@Test
	public void testConnection() {
		try {
			assertTrue(!this.dBAccess.getConnection().isClosed());
		} catch (SQLException e) {
			assertTrue(false);
		}
	}

	@Test
	public void testQueryCategories() {
		Iterator<Category> temp = null;

		try {
			temp = dBAccess.queryCategories().iterator();
		} catch (DatabaseException e) {
			assertFalse(e.getMessage(), true);
		}

		if (temp != null)
			while (temp.hasNext())
				System.out.println(temp.next().getName());
	}

	@Test
	public void testQueryMemos() {
		Iterator<Memo> temp = null;

		try {
			temp = dBAccess.queryMemos().iterator();
		} catch (DatabaseException e) {
			assertFalse(e.getMessage(), true);
		}

		if (temp != null)
			while (temp.hasNext())
				System.out.println(temp.next().getTitle());
	}

	@Test
	public void testAddChildrenToCategory() {
		Category temp = new Category(null);
		temp.setiD((long) 0);

		try {
			dBAccess.addChildrenToCategory(temp);
		} catch (DatabaseException e) {
			assertFalse(e.getMessage(), true);
		}

		temp.setiD((long) 1);

		try {
			dBAccess.addChildrenToCategory(temp);
		} catch (DatabaseException e) {
			assertFalse(e.getMessage(), true);
		}
	}

	@Test
	public void testInsertAndDeleteCategory() {
		Category newCategory = new Category("Sturm");

		assertTrue(this.dBAccess.insertSingleCategory(newCategory));

		Category newCategory2 = new Category("Strum3");
		newCategory2.setParentCategory(newCategory);
		assertTrue(this.dBAccess.insertSingleCategory(newCategory2));

		try {
			assertTrue(dBAccess.deleteCategory(newCategory2));
			assertTrue(dBAccess.deleteCategory(newCategory));
		} catch (Exception E) {
			fail();
		}
	}

	@Test
	public void testDeleteCategory() {

	}

	@Test
	public void testLock() throws Exception {
		Memo newM = new Memo("TesetMittag", true);
		newM.setAuthor("Hans");
		newM.setContent("Schnitzel");
		newM.setLock(newM.getAuthor());

		assertTrue(this.dBAccess.insertMemo(newM));

		try {
			boolean result = dBAccess.lockMemo(newM);
			assertTrue(result);
		} catch (DatabaseException e) {
			fail();
		}
		
		assertTrue(dBAccess.unlockMemo(newM));
		
		dBAccess.deleteMemo(newM);

		return;
	}

	@Test
	public void testinsertMemo() {
		Memo newM = new Memo("TesetMittag", true);
		newM.setAuthor("Hans");
		newM.setContent("Schnitzel");
		newM.setLock(newM.getAuthor());

		assertTrue(this.dBAccess.insertMemo(newM));

		System.out.println("inserted: " + newM.getiD());

		try {
			this.dBAccess.deleteMemo(newM);
		} catch (DatabaseException e) {
			fail();
		}

	}

	@Test
	public void testinsertMemoWithTagAndCat() {
		Memo newM = new Memo("TesetMittag", true);
		newM.setAuthor("Hans");
		newM.setContent("Schnitzel");
		newM.setLock(newM.getAuthor());

		Category newCategory = new Category("Gewitter");
		assertTrue(this.dBAccess.insertSingleCategory(newCategory));
		newM.setCategory(newCategory);

		assertTrue(this.dBAccess.insertMemo(newM));

		try {
			this.dBAccess.deleteMemo(newM);
			this.dBAccess.deleteCategory(newCategory);
		} catch (DatabaseException e) {
			fail();
		}

	}
	
	@Test
	public void fileTest() throws Exception {
		Memo nM = new Memo("FileTestMemo", false);
		nM.setContent("empty");
		File f = new File();
		f.name = "BlaFile Stupid Binary";
		f.memo = nM;
		assertTrue(dBAccess.insertMemo(nM));
		assertTrue(dBAccess.insertSingleFile(f, new FileInputStream("/bin/nano"), 153516));
		
		nM.loadFiles();
		assertTrue(nM.getFiles().size()==1);
		
		FileOutputStream fo=new FileOutputStream(System.getProperty("user.home")
				+ System.getProperty("file.separator") + "nano.txt");
		
		dBAccess.getFileContent(nM.getFiles().get(0), fo);
		fo.close();
		java.io.File file=new java.io.File(System.getProperty("user.home")
				+ System.getProperty("file.separator") + "nano.txt");
		System.out.println(file.length());
		assertTrue(file.length()==153516);
		
		
		dBAccess.deleteFileByFileID(f.id);	
		dBAccess.deleteMemo(nM);
		
	}

	//@Test
	/*public void testUnlock() {
		Memo temp = new Memo(new String(), new Date(), false);
		temp.setiD((long) 3);

		try {
			assertTrue(dBAccess.unlockMemo(temp));
		} catch (DatabaseException e) {
			assertTrue(false);
			// assertFalse(e.getMessage(), true);
		}

		return;
	}*/

}
