package oving7.train;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class TrainTest {

	private CargoCar cc1;
	private CargoCar cc2;
	private PassengerCar pc1;
	private PassengerCar pc2;
	private Train train;

	@BeforeEach
	public void setUp() {
		train = new Train();
		pc1 = new PassengerCar(2000, 200);
		pc2 = new PassengerCar(1500, 100);
		cc1 = new CargoCar(3000, 5000);
		cc2 = new CargoCar(2500, 7000);
	}

	@Test
	@DisplayName("Add cars to train")
	public void testAddCarToTrain() {
		train.addTrainCar(pc1);
		train.addTrainCar(pc2);
		train.addTrainCar(cc1);
		assertTrue(train.contains(pc1),
				"Test if the train contains passenger car 1 after it has been added");
		assertTrue(train.contains(pc2),
				"Test if the train contains passenger car 2 after it has been added");
		assertTrue(train.contains(cc1),
				"Test if the train contains cargo car 1 after it has been added");
		assertFalse(train.contains(cc2),
				"Test if the train contains cargo car 2 without it being added");

		assertThrows(IllegalArgumentException.class, () -> {
			train.addTrainCar(null);
		}, "Test if an IllegalArgumentException is thrown when adding a null car");
	}

	@Test
	@DisplayName("Check total weight of the train")
	public void testTotalTrainWeight() {
		train.addTrainCar(pc1);
		train.addTrainCar(cc1);
		assertEquals(8000 + (2000 + (200 * 80)), train.getTotalWeight(),
				"Test the train's total weight after adding a passenger car and a cargo car");

		train.addTrainCar(pc2);
		assertEquals(8000 + (2000 + (200 * 80)) + (1500 + (100 * 80)), train.getTotalWeight(),
				"Test the train's total weight after adding another passenger car");
	}

	@Test
	@DisplayName("Check passenger count on the train")
	public void testPassengerCount() {
		train.addTrainCar(pc1);
		train.addTrainCar(pc2);
		assertEquals(300, train.getPassengerCount(),
				"Test passenger count after adding passenger cars");

		train.addTrainCar(cc1);
		assertEquals(300, train.getPassengerCount(),
				"Test passenger count after adding a cargo car");
	}

	@Test
	@DisplayName("Check cargo weight on the train")
	public void testCargoWeight() {
		train.addTrainCar(cc1);
		train.addTrainCar(cc2);
		assertEquals(12_000, train.getCargoWeight(), "Test cargo weight after adding cargo cars");

		train.addTrainCar(pc1);
		assertEquals(12_000, train.getCargoWeight(),
				"Test cargo weight after adding a passenger car");
	}
}
