/*-
 *  Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
 * 
 *  This file is part of CityDoctor2.
 *
 *  CityDoctor2 is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  CityDoctor2 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with CityDoctor2.  If not, see <https://www.gnu.org/licenses/>.
 */
package de.hft.stuttgart.citydoctor2.checkresult;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.List;

import org.junit.Test;

import de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportParseException;

public class CheckReportTest {

	@Test
	public void testCheckReportReader() throws CheckReportParseException {
		CheckReport report = CheckReport.load("src/test/resources/errorReportSchema.xml");
		assertNotNull(report);

		Header header = report.getHeader();
		assertNotNull(header);
		ZonedDateTime zdt = header.getDate();
		assertNotNull(zdt);
		ZonedDateTime expZdt = ZonedDateTime.of(2001, 12, 31, 12, 00, 00, 00,
				ZoneId.ofOffset("", ZoneOffset.ofHours(1)));
		assertEquals(expZdt, zdt);

		Environment environment = header.getEnvironment();
		assertNotNull(environment);

		String javaVersion = environment.getJavaVersion();
		String expJavaVersion = "cd:java_version";
		assertEquals(expJavaVersion, javaVersion);

		assertEquals("cd:java_vm_version", environment.getJavaVmVersion());
		assertEquals("cd:java_vm_vendor", environment.getJavaVmVendor());
		assertEquals("cd:os_name", environment.getOsName());
		assertEquals("cd:os_arch", environment.getOsArch());
		assertEquals("cd:city_doctor_validation_version", environment.getValidationVersion());

		assertEquals("cd:file", header.getFile());

		ValidationPlan validationPlan = report.getValidationPlan();
		assertNotNull(validationPlan);
		
		assertEquals(8, validationPlan.getNumberOfRoundingPlaces());
		
		List<PlanCheck> checks = validationPlan.getChecks();
		assertEquals(1, checks.size());
		
		PlanCheck check = checks.get(0);
		assertTrue(check.isActivated());
		assertEquals("", check.getName());

		List<PlanParameter> parameters = check.getParameters();
		assertNotNull(parameters);
		
		assertEquals(1, parameters.size());
		PlanParameter parameter = parameters.get(0);
		assertEquals("", parameter.getName());
		assertEquals("cd:parameter", parameter.getValue());
		
		GlobalStatistics globalStatistics = report.getGlobalStatistics();
		assertNotNull(globalStatistics);
		
		ModelStatistics modelStats = globalStatistics.getModelStats();
		assertEquals(0, modelStats.getNumWaterObjects());
		assertEquals(0, modelStats.getNumBridgeObjects());
		assertEquals(0, modelStats.getNumBuildings());
		assertEquals(0, modelStats.getNumLandObjects());
		assertEquals(0, modelStats.getNumTransportation());
		assertEquals(0, modelStats.getNumVegetation());
		
		GlobalErrorStatistics globalErrorStats = globalStatistics.getGlobalErrorStats();
		assertEquals(0, globalErrorStats.getNumErrorBridgeObjects());
		assertEquals(0, globalErrorStats.getNumErrorBuildings());
		assertEquals(0, globalErrorStats.getNumErrorLandObjects());
		assertEquals(0, globalErrorStats.getNumErrorVegetation());
		assertEquals(0, globalErrorStats.getNumErrorWaterObjects());
		assertEquals(0, globalErrorStats.getNumErrorTransportation());
		
		List<ErrorStatistic> errorStats = globalStatistics.getErrorStats();
		assertEquals(1, errorStats.size());
		
		ErrorStatistic errorStat = errorStats.get(0);
		assertEquals("", errorStat.getName());
		assertEquals(0, errorStat.getCount());
		
		ValidationResults validationResults = report.getValidationResults();
		assertNotNull(validationResults);
		
		List<FeatureReport> bridgeReports = validationResults.getBridgeReports();
		assertEquals(1, bridgeReports.size());
		
		FeatureReport bridgeReport = bridgeReports.get(0);
		Statistics statistics = bridgeReport.getStatistics();
		List<ErrorStatistic> errors = statistics.getErrorStats();
		assertEquals(1, errors.size());
		errorStat = errors.get(0);
		assertEquals("", errorStat.getName());
		assertEquals(0, errorStat.getCount());

		List<ErrorReport> errorReports = bridgeReport.getErrors();
		assertEquals(1, errorReports.size());
		
		ErrorReport errorReport = errorReports.get(0);
		assertEquals("", errorReport.getId());
		assertEquals(ErrorStatus.ERROR, errorReport.getStatus());
		
		Feature feature = errorReport.getFeature();
		assertEquals("", feature.getType());
		assertEquals("", feature.getGmlId());
		
	}
	
	@Test
	public void testDlmReportLoading() throws CheckReportParseException {
		CheckReport report = CheckReport.load("src/test/resources/dlm-report.xml");
		assertNotNull(report);
		
		Header header = report.getHeader();
		assertNotNull(header);
		ZonedDateTime zdt = header.getDate();
		assertNotNull(zdt);
		ZonedDateTime expZdt = ZonedDateTime.of(2019, 6, 6, 15, 47, 45, 221000000,
				ZoneId.ofOffset("", ZoneOffset.ofHours(2)));
		assertEquals(expZdt, zdt);

		Environment environment = header.getEnvironment();
		assertNotNull(environment);

		String javaVersion = environment.getJavaVersion();
		String expJavaVersion = "1.8.0_201";
		assertEquals(expJavaVersion, javaVersion);

		assertEquals("25.201-b09", environment.getJavaVmVersion());
		assertEquals("Oracle Corporation", environment.getJavaVmVendor());
		assertEquals("Windows 10", environment.getOsName());
		assertEquals("amd64", environment.getOsArch());
		assertEquals("3.2.0", environment.getValidationVersion());

		assertEquals("Delft_Part.gml", header.getFile());

		ValidationPlan validationPlan = report.getValidationPlan();
		assertNotNull(validationPlan);
		assertEquals(8, validationPlan.getNumberOfRoundingPlaces());
		
		List<PlanCheck> checks = validationPlan.getChecks();
		assertEquals(18, checks.size());
		
		PlanCheck check = checks.get(0);
		assertTrue(check.isActivated());
		assertEquals("C_GE_R_TOO_FEW_POINTS", check.getName());

		check = checks.get(7);
		assertEquals("C_GE_P_NON_PLANAR", check.getName());
		
		List<PlanParameter> parameters = check.getParameters();
		assertEquals(3, parameters.size());
		PlanParameter parameter = parameters.get(0);
		assertEquals("angleTolerance", parameter.getName());
		assertEquals("0.1", parameter.getValue());

		GlobalStatistics globalStatistics = report.getGlobalStatistics();
		assertNotNull(globalStatistics);
		
		ModelStatistics modelStats = globalStatistics.getModelStats();
		assertEquals(3, modelStats.getNumWaterObjects());
		assertEquals(3, modelStats.getNumBridgeObjects());
		assertEquals(160, modelStats.getNumBuildings());
		assertEquals(81, modelStats.getNumLandObjects());
		assertEquals(143, modelStats.getNumTransportation());
		assertEquals(126, modelStats.getNumVegetation());
		
		GlobalErrorStatistics globalErrorStats = globalStatistics.getGlobalErrorStats();
		assertEquals(3, globalErrorStats.getNumErrorBridgeObjects());
		assertEquals(0, globalErrorStats.getNumErrorBuildings());
		assertEquals(3, globalErrorStats.getNumErrorLandObjects());
		assertEquals(2, globalErrorStats.getNumErrorVegetation());
		assertEquals(1, globalErrorStats.getNumErrorWaterObjects());
		assertEquals(11, globalErrorStats.getNumErrorTransportation());

		List<ErrorStatistic> errorStats = globalStatistics.getErrorStats();
		assertEquals(2, errorStats.size());
		
		ErrorStatistic errorStat = errorStats.get(0);
		assertEquals("GE_R_SELF_INTERSECTION", errorStat.getName());
		assertEquals(4, errorStat.getCount());
		
		ValidationResults validationResults = report.getValidationResults();
		assertNotNull(validationResults);
		
		List<FeatureReport> bridgeReports = validationResults.getBridgeReports();
		assertEquals(3, bridgeReports.size());
		
		FeatureReport bridgeReport = bridgeReports.get(0);
		assertEquals("bea632f90-00b8-11e6-b420-2bdcc4ab5d7f", bridgeReport.getGmlId());
		
		Statistics statistics = bridgeReport.getStatistics();
		List<ErrorStatistic> errors = statistics.getErrorStats();
		assertEquals(1, errors.size());
		errorStat = errors.get(0);
		assertEquals("GE_R_TOO_FEW_POINTS", errorStat.getName());
		assertEquals(70, errorStat.getCount());

		List<ErrorReport> errorReports = bridgeReport.getErrors();
		assertEquals(70, errorReports.size());
		
		ErrorReport errorReport = errorReports.get(0);
		assertEquals("GE_R_TOO_FEW_POINTS", errorReport.getId());
		assertEquals(ErrorStatus.ERROR, errorReport.getStatus());
		
		List<FeatureReport> buildingReports = validationResults.getBuildingReports();
		assertEquals(160, buildingReports.size());
		
		List<FeatureReport> landReports = validationResults.getLandReports();
		assertEquals(81, landReports.size());
		
		List<FeatureReport> transportationReports = validationResults.getTransportationReports();
		assertEquals(143, transportationReports.size());
		
		List<FeatureReport> vegetationReports = validationResults.getVegetationReports();
		assertEquals(126, vegetationReports.size());
		
		List<FeatureReport> waterReports = validationResults.getWaterReports();
		assertEquals(3, waterReports.size());
		
	}

}
