import junit.framework.TestCase;

import java.util.List;
import java.util.Calendar;
import java.util.logging.Logger;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
import java.math.BigDecimal;

public class ProductShipperV2Test extends TestCase {
    private ProductShipperV2 productShipper;
    private Product product;

    protected void setUp() throws Exception {
        productShipper = new ProductShipperV2();
        product = new Product();
    }

    public void testCalculateChargesWithEvenNumberOfKilosProduct() {
        productShipper.setCalendar(new RealCalendar());
        product.setWeightInKilograms(3);

        assertEquals(new BigDecimal(3.75), productShipper.calculateShippingCharges(product));

    }

    public void testCalculateChargesWithFractionalWeightProduct() {
        productShipper.setCalendar(new RealCalendar());
        product.setWeightInKilograms(1.5f);

        assertEquals(new BigDecimal(1.875), productShipper.calculateShippingCharges(product));

    }

    public void testCalculateChargesIncludesAdditionalChargesDuringChristmas() {
        MockCalendar calendar = initializeCalendar();
        productShipper.setCalendar(calendar);
        product.setWeightInKilograms(1.5f);

        assertEquals(new BigDecimal(1.875 + 2), productShipper.calculateShippingCharges(product));

    }

    private MockCalendar initializeCalendar() {
        MockCalendar calendar = new MockCalendar();
        calendar.setMonth(Calendar.DECEMBER);
        calendar.setDay(26);
        return calendar;
    }

    public void testCalculateChargesThrowsExceptionWithZeroWeightProduct() {
        product.setWeightInKilograms(0f);

        try {
            productShipper.calculateShippingCharges(product);
            fail("Expected exception not thrown");
        } catch (IllegalArgumentException expected) {
            assertTrue(true);
        }

    }

    public void testCalculateChargesThrowsExceptionWithNegativeWeightProduct() {
        product.setWeightInKilograms(-1.25f);

        try {
            productShipper.calculateShippingCharges(product);
            fail("Expected exception not thrown");
        } catch (IllegalArgumentException expected) {
            assertTrue(true);
        }

    }

    public void testCalculateChargesNeedsCalendarSet() {
        product.setWeightInKilograms(3f);

        try {
            productShipper.calculateShippingCharges(product);
            fail("Expected exception not thrown");
        } catch (NullPointerException expected) {
            assertTrue(true);
        }

    }
}
