/*-
 *  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/>.
 */
import java.util.List;

import de.hft.stuttgart.citydoctor2.checkresult.CheckReport;
import de.hft.stuttgart.citydoctor2.checkresult.EdgeReport;
import de.hft.stuttgart.citydoctor2.checkresult.Environment;
import de.hft.stuttgart.citydoctor2.checkresult.ErrorDetails;
import de.hft.stuttgart.citydoctor2.checkresult.ErrorReport;
import de.hft.stuttgart.citydoctor2.checkresult.ErrorStatistic;
import de.hft.stuttgart.citydoctor2.checkresult.FeatureReport;
import de.hft.stuttgart.citydoctor2.checkresult.GlobalErrorStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.GlobalStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.Header;
import de.hft.stuttgart.citydoctor2.checkresult.ModelStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.PlanCheck;
import de.hft.stuttgart.citydoctor2.checkresult.PlanParameter;
import de.hft.stuttgart.citydoctor2.checkresult.Statistics;
import de.hft.stuttgart.citydoctor2.checkresult.ValidationPlan;
import de.hft.stuttgart.citydoctor2.checkresult.ValidationResults;
import de.hft.stuttgart.citydoctor2.checkresult.VertexReport;
import de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportParseException;

public class CheckReportTest {
	
	public static void main(String[] args) throws CheckReportParseException {
//		String file = args[0];
		String file = "output.xml";
		CheckReport report = CheckReport.load(file);
		Header header = report.getHeader();
		System.out.println("File: " + header.getFile());
		System.out.println("Time: " + header.getDate());
		Environment environment = header.getEnvironment();
		System.out.println("Java version: " + environment.getJavaVersion());
		System.out.println("Java VM Vendor: " + environment.getJavaVmVendor());
		System.out.println("Java VM Version: " + environment.getJavaVmVersion());
		System.out.println("OS Architecture: " + environment.getOsArch());
		System.out.println("OS Name: " + environment.getOsName());
		System.out.println("Validation Version: " + environment.getValidationVersion());
		
		ValidationPlan validationPlan = report.getValidationPlan();
		
		System.out.println();
		System.out.println("ValidationPlan:");
		System.out.println("minVertexDistance: " + validationPlan.getNumberOfRoundingPlaces());
		
		for (PlanCheck pCheck : validationPlan.getChecks()) {
			System.out.println("Check: " + pCheck.getName());
			System.out.println("\tEnabled: " + pCheck.isActivated());
			if (!pCheck.getParameters().isEmpty()) {
				for (PlanParameter para : pCheck.getParameters()) {
					System.out.println("\tParameter: " + para.getName() + "=" + para.getValue());
				}
			}
		}
		
		GlobalStatistics globalStatistics = report.getGlobalStatistics();
		List<ErrorStatistic> errorStats = globalStatistics.getErrorStats();
		System.out.println();
		System.out.println("ErrorStatistics:");
		for (ErrorStatistic eStat : errorStats) {
			System.out.println("Error " + eStat.getName() + " occured " + eStat.getCount() + " times");
		}
		
		ModelStatistics modelStats = globalStatistics.getModelStats();
		System.out.println();
		System.out.println("ModelStatistics:");
		System.out.println("Number of Buildings: " + modelStats.getNumBuildings());
		System.out.println("Number of Bridges: " + modelStats.getNumBridgeObjects());
		System.out.println("Number of Vegetation: " + modelStats.getNumVegetation());
		System.out.println("Number of WaterObjects: " + modelStats.getNumWaterObjects());
		System.out.println("Number of Transportation: " + modelStats.getNumTransportation());
		System.out.println("Number of LandObjects: " + modelStats.getNumLandObjects());
		
		GlobalErrorStatistics globalErrorStats = globalStatistics.getGlobalErrorStats();
		System.out.println("Errornous Feature Statistics");
		System.out.println("Number of Buildings: " + globalErrorStats.getNumErrorBuildings());
		System.out.println("Number of Bridges: " + globalErrorStats.getNumErrorBridgeObjects());
		System.out.println("Number of Vegetation: " + globalErrorStats.getNumErrorVegetation());
		System.out.println("Number of WaterObjects: " + globalErrorStats.getNumErrorWaterObjects());
		System.out.println("Number of Transportation: " + globalErrorStats.getNumErrorTransportation());
		System.out.println("Number of LandObjects: " + globalErrorStats.getNumErrorLandObjects());
		
		ValidationResults validationResults = report.getValidationResults();
		System.out.println();
		System.out.println("ValidationResults:");
		
		/*
		 * Alternative way to access the validation results by using the gmlID of a feature:
		 * 
		 * 		FeatureReport featureReportForId = report.getFeatureReportForId("GML-ID");
		 */
		System.out.println("Buildings:");
		printReports(validationResults.getBuildingReports());
		
		System.out.println("Vegetation:");
		printReports(validationResults.getVegetationReports());

		System.out.println("Bridges:");
		printReports(validationResults.getBridgeReports());

		System.out.println("WaterObjects:");
		printReports(validationResults.getWaterReports());

		System.out.println("LandObjects:");
		printReports(validationResults.getLandReports());

		System.out.println("Transportation:");
		printReports(validationResults.getTransportationReports());
	}

	private static void printReports(List<FeatureReport> reports) {
		for (FeatureReport fReport : reports) {
			System.out.println("GML-ID: " + fReport.getGmlId());
			Statistics statistics = fReport.getStatistics();
			if (statistics != null && statistics.getErrorStats() != null && !statistics.getErrorStats().isEmpty()) {
				System.out.println("\tStatistics:");
				for (ErrorStatistic eStat : statistics.getErrorStats()) {
					System.out.println("\tError " + eStat.getName() + " occured " + eStat.getCount() + " times");
				}
			}

			List<ErrorReport> errors = fReport.getErrors();
			if (!errors.isEmpty()) {
				System.out.println("\tErrors:");
			}
			for (ErrorReport errReport : errors) {
				System.out.println("\tError ID: " + errReport.getId() + " with status: " + errReport.getStatus());
				ErrorDetails errorDetails = errReport.getErrorDetails();
				if (errorDetails != null) {
					System.out.println("\tError Details:");
					for (EdgeReport edgeReport : errorDetails.getEdge()) {
						if (edgeReport.getName() != null) {
							System.out.println("\t\t" + edgeReport.getName());
						}
						System.out.println("\t\t" + toString(edgeReport));
					}
					// more details
				}
			}
			System.out.println();
		}
	}

	private static String toString(EdgeReport edgeReport) {
		return "Edge from: " + toString(edgeReport.getFrom()) + " to " + toString(edgeReport.getTo());
	}

	private static String toString(VertexReport from) {
		return "Vertex[" + from.getX() + ", " + from.getY() + ", " + from.getZ() + "]";
	}
}
