/*-
 *  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.check;

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

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.junit.Test;

import de.hft.stuttgart.citydoctor2.check.error.SchematronError;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;

public class CheckableTest {

	@Test
	public void testValidated() {
		Checkable c = new Checkable() {

			private static final long serialVersionUID = -8913364710109207353L;

			@Override
			public GmlId getGmlId() {
				return null;
			}

			@Override
			public void prepareForChecking() {

			}

			@Override
			public void clearMetaInformation() {

			}

			@Override
			public void clearAllContainedCheckResults() {
			}

			@Override
			public Class<? extends Checkable> getCheckClass() {
				return Building.class;
			}

		};
		Check check = new Check() {

			@Override
			public Set<Requirement> appliesToRequirements() {
				return null;
			}

			@Override
			public CheckId getCheckId() {
				return null;
			}

			@Override
			public RequirementType getType() {
				return null;
			}

			@Override
			public Check createNewInstance() {
				return null;
			}

		};
		assertFalse(c.isValidated());
		c.accept(check);
		assertTrue(c.isValidated());
		c.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, null, null));
		assertEquals(1, c.getAllCheckResults().size());
		c.clearCheckResults();
		assertFalse(c.isValidated());
		assertTrue(c.getAllCheckResults().isEmpty());
	}

	@Test
	public void testContainsError() {
		Building b = new Building();
		Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0);
		b.addGeometry(geom);
		assertFalse(b.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
		assertFalse(b.containsAnyError());
		geom.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR,
				new SchematronError(null, null, null, null)));
		assertTrue(b.containsAnyError());
		assertTrue(b.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
		geom.addCheckResult(new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.DEPENDENCIES_NOT_MET,
				new SchematronError(null, null, null, null)));
		assertTrue(b.containsError(CheckId.C_GE_P_INNER_RINGS_NESTED));
		geom.addCheckResult(new CheckResult(CheckId.C_GE_P_INTERIOR_DISCONNECTED, ResultStatus.OK,
				new SchematronError(null, null, null, null)));
		assertFalse(b.containsError(CheckId.C_GE_P_INTERIOR_DISCONNECTED));
	}

	@Test
	public void testContainsAnyErrorNoError() {
		Building b = new Building();
		b.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
		assertFalse(b.containsAnyError());
	}

	@Test
	public void testContainsAnyErrorError() {
		Building b = new Building();
		b.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR,
				new SchematronError(null, null, null, null)));
		assertTrue(b.containsAnyError());
	}
	
	@Test
	public void testContainsAnyErrorDependencyNotMetError() {
		Building b = new Building();
		b.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.DEPENDENCIES_NOT_MET,
				new SchematronError(null, null, null, null)));
		assertTrue(b.containsAnyError());
	}

	@Test
	public void hasDependencyNotMetErrorNoError() {
		Building b = new Building();
		b.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
		assertFalse(b.hasDependencyNotMetError(CheckId.C_GE_P_HOLE_OUTSIDE));
		assertFalse(b.hasDependencyNotMetError(CheckId.C_GE_P_INNER_RINGS_NESTED));
	}

	@Test
	public void hasDependencyNotMetErrorError() {
		Building b = new Building();
		b.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR,
				new SchematronError(null, null, null, null)));
		assertFalse(b.hasDependencyNotMetError(CheckId.C_GE_P_HOLE_OUTSIDE));
	}

	@Test
	public void testCollectAllContainedErrors() {
		Building b = new Building();
		Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0);
		b.addGeometry(geom);
		b.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR,
				new SchematronError(null, null, null, null)));
		geom.addCheckResult(new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.DEPENDENCIES_NOT_MET,
				new SchematronError(null, null, null, null)));
		geom.addCheckResult(new CheckResult(CheckId.C_GE_P_INTERIOR_DISCONNECTED, ResultStatus.ERROR,
				new SchematronError(null, null, null, null)));
		List<CheckError> errors = new ArrayList<>();
		b.collectContainedErrors(errors);
		assertEquals(2, errors.size());
	}

	@Test
	public void testCheckClass() {
		Building b = new Building();
		assertEquals(Building.class, b.getCheckClass());
	}

}
