package org.eclipse.openk.sp.controller.reports;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.eclipse.birt.report.engine.api.EngineException;
import org.eclipse.birt.report.engine.api.IReportEngine;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
import org.eclipse.openk.sp.db.converter.EntityConverter;
import org.eclipse.openk.sp.db.dao.StandbyGroupRepository;
import org.eclipse.openk.sp.db.dao.StandbyListRepository;
import org.eclipse.openk.sp.db.dao.StandbyScheduleBodyRepository;
import org.eclipse.openk.sp.db.dao.UserRepository;
import org.eclipse.openk.sp.db.model.StandbyGroup;
import org.eclipse.openk.sp.db.model.StandbyList;
import org.eclipse.openk.sp.db.model.StandbyScheduleBody;
import org.eclipse.openk.sp.db.model.User;
import org.eclipse.openk.sp.dto.StandbyGroupSelectionDto;
import org.eclipse.openk.sp.dto.report.ReportDto;
import org.eclipse.openk.sp.dto.report.ReportInputDto;
import org.eclipse.openk.sp.exceptions.SpException;
import org.eclipse.openk.sp.util.FileHelper;
import org.eclipse.openk.sp.util.FileHelperTest;
import org.eclipse.openk.sp.util.GsonTypeHelper;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.web.MockHttpServletResponse;

import com.google.gson.Gson;

@RunWith(MockitoJUnitRunner.class)
public class ReportControllerTest {

	protected static final Logger LOGGER = Logger.getLogger(ReportController.class);

	@InjectMocks
	ReportController reportController;

	@Mock
	FileHelper fileHelper;

	@Mock
	StandbyGroupRepository standbyGroupRepository;

	@Mock
	UserRepository userRepository;

	@Mock
	StandbyListRepository standbyListRepository;

	@Mock
	StandbyScheduleBodyRepository standbyScheduleBodyRepository;

	@Mock
	private EntityConverter entityConverter;

	@Test
	public void initialiseBirtEngineTest() {

		assertNotNull(reportController.initialiseBirtEngine());
	}

	@Test
	public void testGenerateReport() throws IOException, SpException {

		ReportDto reportDto = new ReportDto();
		reportDto.setReportName("Wochenübersicht");
		reportDto.setPrintFormat("pdf");
		StandbyList standbyList = new StandbyList();
		standbyList.setId(1L);
		standbyList.setTitle("Elektriker");
		reportDto.setStandByList(standbyList);
		reportDto.setReportLevel("Plan-Ebene");
		reportDto.setValidFrom(new Date());
		reportDto.setValidTo(new Date());

		StandbyGroup standbyGroup = new StandbyGroup();
		standbyGroup.setId(1L);
		standbyList.getLsStandbyGroups().add(standbyGroup);

		when(standbyListRepository.findOne(any())).thenReturn(standbyList);
		when(standbyGroupRepository.findOne(any())).thenReturn(standbyGroup);

		try {
			reportController.generateReport(reportDto);
			assertTrue(false);
		} catch (SpException e) {
			assertTrue(true);
		}

		reportDto.setReportLevel("Ist-Ebene");

		try {
			reportController.generateReport(reportDto);
			assertTrue(false);
		} catch (SpException e) {
			assertTrue(true);
		}

		reportDto.setStandByList(null);
		reportDto.setStandByGroup(standbyGroup);

		try {
			reportController.generateReport(reportDto);
			assertTrue(false);
		} catch (Exception e) {
			assertTrue(true);
		}

		reportDto.setStandByGroup(null);
		reportDto.setUserId(1L);

		try {
			reportController.generateReport(reportDto);
			assertTrue(false);
		} catch (SpException e) {
			assertTrue(true);
		}

	}

	@Ignore
	@Test
	public void flushReportFile() {

		try {
			File mockFile = new ClassPathResource("reports" + File.separator + "Negativtest.txt").getFile();
			File fileToDelete = new ClassPathResource("reports").getFile();
			fileToDelete = new File(fileToDelete.getAbsolutePath() + File.separator + "fileToDelete.pdf");
			copyFileUsingFileChannels(mockFile, fileToDelete);
			assertTrue(fileToDelete.exists());
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			reportController.flushReportFile(fileToDelete, out);
			assertFalse(fileToDelete.exists());
			fileToDelete = new File(fileToDelete.getAbsolutePath() + File.separator + "fileNotExists.pdf");
			reportController.flushReportFile(fileToDelete, out);
			assertFalse(fileToDelete.exists());

		} catch (IOException e) {
			LOGGER.error(e, e);
		}
	}

	private static void copyFileUsingFileChannels(File source, File dest) throws IOException {
		FileChannel inputChannel = null;
		FileChannel outputChannel = null;
		try {
			inputChannel = new FileInputStream(source).getChannel();
			outputChannel = new FileOutputStream(dest).getChannel();
			outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
		} finally {
			inputChannel.close();
			outputChannel.close();
		}
	}

	@Ignore
	@Test
	public void setResponseData() {

		ReportDto reportDto = new ReportDto();
		reportDto.setReportName("Wochenübersicht");
		reportDto.setPrintFormat("pdf");

		MockHttpServletResponse response = new MockHttpServletResponse();
		reportController.setResponseData(response, reportDto);

		assertEquals("application/" + reportDto.getPrintFormat(), response.getContentType());
		assertEquals("attachment; filename=" + reportDto.getReportName() + "." + reportDto.getPrintFormat(),
				response.getHeader("Content-disposition"));
	}

	@Test
	public void initTest() throws IOException {
		String text = "/reports";

		Properties p = new Properties();
		p.setProperty("reports.path", text);
		p.setProperty("reports.workdirectory", text);

		File f = File.createTempFile("test", "test");
		File f2 = File.createTempFile("test", "test");

		when(fileHelper.loadPropertiesFromResource(any())).thenReturn(p);
		when(fileHelper.loadFolderFromFileSystemOrResource(Mockito.anyString(), Mockito.anyBoolean())).thenReturn(f);
		when(fileHelper.loadFileFromFileSystemOrResource(Mockito.anyString(), Mockito.anyString(),
				Mockito.anyBoolean())).thenReturn(f2);
		String result = reportController.init();
		assertEquals(text, result);

	}

	@Test
	@Ignore
	public void getReports() {

		Properties p = new Properties();
		p.setProperty("reports.path", "/reports");
		p.setProperty("reports.workdirectory", "/reports");

		File f = new File("asd");

		try {
			when(fileHelper.loadPropertiesFromResource(any())).thenReturn(p);

			List<ReportDto> result = reportController.getReports();
			assertNotNull(result);

			p.setProperty("reports.path", "/extra.fehlschlagen");

			when(reportController.init()).thenThrow(new IOException());

			result = reportController.getReports();

		} catch (IOException e) {
			LOGGER.error(e, e);
			assertNull(e);
		} catch (SpException e) {
			LOGGER.error(e, e);
			assertNull(e);
		}
	}

	@Ignore
	@Test
	public void performReportQueryTest() throws SpException {
		FileHelperTest fh = new FileHelperTest();
		String json = fh.loadStringFromResource("testStandbyList.json");

		StandbyList standbyList = (StandbyList) new Gson().fromJson(json, StandbyList.class);
		standbyList.setId(1l);

		json = fh.loadStringFromResource("testStandbyGroup.json");
		StandbyGroupSelectionDto standbyGroupSelectionDto = (StandbyGroupSelectionDto) new Gson().fromJson(json,
				StandbyGroupSelectionDto.class);

		json = fh.loadStringFromResource("testStandbyScheduleBodySearchList.json");
		List<StandbyScheduleBody> lsStandbyScheduleBody = (List<StandbyScheduleBody>) new Gson().fromJson(json,
				GsonTypeHelper.JSON_TYPE_STANDBYBODY_ARRAY_LIST);

		ReportDto reportDto = new ReportDto();
		reportDto.setReportName("Wochenübersicht");
		reportDto.setPrintFormat("pdf");
		reportDto.setStandByList(standbyList);
		reportDto.setReportLevel("Plan-Ebene");

		when(standbyListRepository.findOne(any())).thenReturn(standbyList);
		when(standbyScheduleBodyRepository.findByGroupsAndDateAndStatus(Mockito.any(), Mockito.any(), Mockito.any(),
				Mockito.any())).thenReturn(lsStandbyScheduleBody);

		List<StandbyScheduleBody> result = reportController.performReportQuery(reportDto);
		assertNotNull(result);

	}

	@Test(expected = SpException.class)
	public void performReportQueryExceptionTest() throws SpException {

		ReportDto reportDto = new ReportDto();
		reportDto.setReportName("Wochenübersicht");
		reportDto.setPrintFormat("pdf");
		StandbyList standbyList = new StandbyList();
		standbyList.setId(1L);
		standbyList.setTitle("Elektriker");
		reportDto.setStandByList(standbyList);
		reportDto.setReportLevel("Plan-Ebene");

		StandbyGroup standbyGroup = new StandbyGroup();
		standbyGroup.setId(1L);
		standbyList.getLsStandbyGroups().add(standbyGroup);

		when(standbyListRepository.findOne(any())).thenReturn(standbyList);

		List<StandbyScheduleBody> result = reportController.performReportQuery(reportDto);
		assertNotNull(result);

	}

	@Test(expected = SpException.class)
	public void performReportQueryException2Test() throws SpException {

		ReportDto reportDto = new ReportDto();
		reportDto.setReportName("Wochenübersicht");
		reportDto.setPrintFormat("pdf");
		reportDto.setReportLevel("Plan-Ebene");

		List<StandbyScheduleBody> result = reportController.performReportQuery(reportDto);
		assertNotNull(result);

	}

	@Test
	public void setTaskParameters() throws EngineException, ParseException {
		String text = "test";
		Date dateStr = new Date();
		FileHelperTest fh = new FileHelperTest();
		ReportDto reportDto = new ReportDto();
		reportDto.setReportName("Wochenübersicht");
		reportDto.setReportName(null);

		InputStream rptdFileStream = fh.loadFromResource("test.rptdesign");

		IReportEngine engine = reportController.initialiseBirtEngine();
		IReportRunnable iReportRunnable = engine.openReportDesign(rptdFileStream);
		IRunAndRenderTask task = engine.createRunAndRenderTask(iReportRunnable);

		boolean result = reportController.setTaskParameters(task, reportDto);
		assertEquals(true, result);

		result = reportController.setTaskParameters(task, null);
		assertEquals(true, result);

		reportDto.setReportName(text);
		reportDto.setValidTo(dateStr);
		reportDto.setValidFrom(dateStr);
		reportDto.setReportLevel("Plan-Ebene");
		reportDto.setPrintFormat("PDF");
		reportDto.setUserId(1L);
		StandbyList standByList = new StandbyList();
		standByList.setTitle(text);
		reportDto.setStandByList(standByList);

		String json = fh.loadStringFromResource("testUser.json");

		User user = (User) new Gson().fromJson(json, User.class);

		Mockito.when(userRepository.findOne(Mockito.anyLong())).thenReturn(user);

		result = reportController.setTaskParameters(task, reportDto);
		assertEquals(true, result);

	}

	@Test
	public void testDateSettings() {

		StandbyScheduleBody body = new StandbyScheduleBody();
		body.setValidFrom(new Date());
		body.setValidTo(new Date());

		reportController.calcReportStartDate(body);
		assertNotNull(body.getStartDateStr());

		reportController.calcReportEndDate(body);
		assertNotNull(body.getEndDateStr());

	}

	@Test
	public void compress1ResultOnGroups() {
		FileHelperTest fh = new FileHelperTest();
//		List<ReportInputDto> 
		ReportDto reportDto = new ReportDto();
		reportDto.setReportName("Wochenübersicht");

		String json = fh.loadStringFromResource("testStandbyScheduleBodySearchList.json");
		List<StandbyScheduleBody> lsStandbyScheduleBody = (List<StandbyScheduleBody>) new Gson().fromJson(json,
				GsonTypeHelper.JSON_TYPE_STANDBYBODY_ARRAY_LIST);

		List<ReportInputDto> result = reportController.compress1ResultOnGroups(reportDto, lsStandbyScheduleBody);
		assertNotNull(result);

	}

}
