package simulation.simulators.runners;

import company.company.Company;
import company.delivery.Delivery;
import company.delivery.DeliveryStatus;
import company.order.Order;
import economy.Economy;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import simulation.generators.CompanyGenerator;
import simulation.generators.DataGenerator;
import simulation.simulators.SupplyChainControlSimulator;

import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * Created by Arthur Deschamps on 14.06.17.
 * @author Arthur Deschamps
 * @since 1.0
 */
public class CompanyAbstractSimulatorInterfaceTest {

    private static EconomySimulatorRunner economySimulator;
    private static CompanySimulatorRunner companySimulator;
    private static Company company;
    private static Economy economy;
    private static final Logger logger = LoggerFactory.getLogger(SupplyChainControlSimulator.class);


    @BeforeClass
    public static void setUp() {

        company = CompanyGenerator.generateLocalCompany();
        economy = new Economy();
        // Make sure company has client to speed up the tests
        for (int i = 0; i < 10; i++) {
            company.newCustomer(new DataGenerator(company).generateRandomCustomer());
        }

        economySimulator = new EconomySimulatorRunner(economy);
        companySimulator = new CompanySimulatorRunner(company, economy);

        ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
    }

    private void run() {
        economySimulator.run();
        companySimulator.run();
    }

    @Test
    public void testProductProduction() {
        /*
            Now that we have a product or multiple product types, we should be able to create products
         */
        try {
            int totalAmountOfProducts = company.getProducts().size();
            for (int i = 0; i < Math.pow(10, 7); i++) {
                run();
                if (totalAmountOfProducts < company.getProducts().size())
                    return;
                totalAmountOfProducts = company.getProducts().size();
            }

            Assert.fail("No product ever created.");

        } catch (Exception e) {
            Assert.fail();
            e.printStackTrace();
        }

    }

    @Test
    public void testProductTypeCreation() {
        try {
            int productTypesSize = company.getProductTypes().size();
            for (int i = 0; i < Math.pow(10, 6); i++) {
                // Speed up the test by augmenting chances for type creation
                economy.setDemand(1);
                economy.setGrowth(10);
                economy.setSectorConcurrency(0);

                run();
                if (productTypesSize < company.getProductTypes().size())
                    return;
                productTypesSize = company.getProductTypes().size();
            }

            Assert.fail("No product type ever created.");

        } catch (Exception e) {
            Assert.fail();
            e.printStackTrace();
        }
    }

    @Test
    public void testProductTypeDestruction() {
        try {
            int currentSize = company.getProductTypes().size();

            for (int i = 0; i < Math.pow(10, 7); i++) {
                run();
                // Removes every orders (higher chance that a type is going to be destructed)
                company.getOrders().removeAll(company.getOrders());
                if (currentSize > company.getProductTypes().size())
                    return;
                currentSize = company.getProductTypes().size();
            }

            Assert.fail("No product type ever destroyed.");

        } catch (Exception e) {
            Assert.fail();
            e.printStackTrace();
        }
    }

    @Test
    public void testOrders() {
        try {
            int orderAmount = company.getOrders().size();
            for (int i = 0; i < Math.pow(10, 7); i++) {
                run();
                if (orderAmount < company.getOrders().size())
                    return;
                orderAmount = company.getOrders().size();
            }

            Assert.fail("No order ever made by any customer.");
        } catch (Exception e) {
            Assert.fail();
            e.printStackTrace();
        }
    }

    @Test
    public void testDeliveryStatusUpdate() {
        try {
            DataGenerator dataGenerator = new DataGenerator(company);
            final Optional<Order> orderOptional = dataGenerator.generateRandomOrder();
            Assert.assertTrue(orderOptional.isPresent());
            company.newOrder(orderOptional.get());
            final Delivery delivery = dataGenerator.generateRandomDelivery().get();
            Assert.assertEquals(DeliveryStatus.WAREHOUSE,delivery.getDeliveryState());
            company.newDelivery(delivery);
            Assert.assertTrue(company.getDeliveries().contains(delivery));

            for (int i = 0; i < Math.pow(10, 7); i++) {
                run();
                if (delivery.getDeliveryState().equals(DeliveryStatus.TRANSIT))
                    return;
            }

            Assert.fail("Delivery status never passed from 'warehouse' to 'shipped'.");
        } catch (Exception e) {
            Assert.fail();
            e.printStackTrace();
        }
    }

}

@@ -69,110 +69,8 @@
 ny;%0A
-import company.delivery.Delivery;%0Aimport company.delivery.DeliveryStatus;%0Aimport company.order.Order;%0A
 impo
@@ -378,35 +378,8 @@
 r;%0A%0A
-import java.util.Optional;%0A
 impo
@@ -4293,1030 +4293,6 @@
  %7D%0A%0A
-    @Test%0A    public void testDeliveryStatusUpdate() %7B%0A        try %7B%0A            DataGenerator dataGenerator = new DataGenerator(company);%0A            final Optional%3COrder%3E orderOptional = dataGenerator.generateRandomOrder();%0A            Assert.assertTrue(orderOptional.isPresent());%0A            company.newOrder(orderOptional.get());%0A            final Delivery delivery = dataGenerator.generateRandomDelivery().get();%0A            Assert.assertEquals(DeliveryStatus.WAREHOUSE,delivery.getDeliveryState());%0A            company.newDelivery(delivery);%0A            Assert.assertTrue(company.getDeliveries().contains(delivery));%0A%0A            for (int i = 0; i %3C Math.pow(10, 7); i++) %7B%0A                run();%0A                if (delivery.getDeliveryState().equals(DeliveryStatus.TRANSIT))%0A                    return;%0A            %7D%0A%0A            Assert.fail(%22Delivery status never passed from 'warehouse' to 'shipped'.%22);%0A        %7D catch (Exception e) %7B%0A            Assert.fail();%0A            e.printStackTrace();%0A        %7D%0A    %7D%0A%0A
 %7D%0A

Remove unnecessary test