public void PowerPlanLoad_WindTurbine_NeedToCalculateRealPowerAndToFloorToOneDigitAfterDecimalPoint()
        {
            // Arrange & Act
            var result = new PowerPlantLoad("Test", PowerPlantType.WindTurbine, 0, 85, 25.4m, 0);

            // Assert
            result.RealPMin.Should().Be(0);
            result.RealPMax.Should().Be(21.5m);
        }
        public void PowerPlanLoad_GasFiredWithPMinAndPMaxAsInteger_NoNeedToChangePMinAndPMax()
        {
            // Arrange & Act
            var result = new PowerPlantLoad("Test", PowerPlantType.GasFired, 100, 200, 80, 0);

            // Assert
            result.RealPMin.Should().Be(100);
            result.RealPMax.Should().Be(200);
        }
        public void PowerPlanLoad_WindTurbine_NeedToCalculateRealPowerButNoNeedToFloor()
        {
            // Arrange & Act
            var result = new PowerPlantLoad("Test", PowerPlantType.WindTurbine, 0, 36, 60, 0);

            // Assert
            result.RealPMin.Should().Be(0);
            result.RealPMax.Should().Be(21.6m);
        }
        /// <summary>
        /// Calculate how much power the powerplant will deliver in order to achieve the requested load
        /// </summary>
        private static (decimal, decimal) CalculateOutputPowerPlant(PowerPlantLoad powerPlantLoad,
                                                                    IEnumerable <PowerPlantLoad> previousPowerPlantLoads, decimal remainingLoadToPlan)
        {
            // The request load is already supplied, so no need to power this powerplant
            if (remainingLoadToPlan == 0)
            {
                return(0, 0);
            }

            // The load needed is between RealPMin and RealPMax so use the remaining load as load for this powerplant
            if (powerPlantLoad.RealPMin <= remainingLoadToPlan && remainingLoadToPlan <= powerPlantLoad.RealPMax)
            {
                return(remainingLoadToPlan, 0);
            }

            // The load needed is greater than RealPMax of the powerplant
            // So use maximum power of the plan and subtract it from the remaining
            if (remainingLoadToPlan > powerPlantLoad.RealPMax)
            {
                return(powerPlantLoad.RealPMax, remainingLoadToPlan - powerPlantLoad.RealPMax);
            }

            // The load needed is lesser than RealPMin of the powerplant
            // Calculate the extra power produced by using the RealPMin of this powerplant
            var extraPower = powerPlantLoad.RealPMin - remainingLoadToPlan;
            var previousPowerPlantLoadsList = previousPowerPlantLoads.ToList();

            // Check if we can remove this extra power from previous powerplants already calculated
            // If not don't use this powerplant for the load
            if (!CanAdaptPreviousPowerPlantLoads(previousPowerPlantLoadsList, extraPower))
            {
                return(0, remainingLoadToPlan);
            }

            // Adapt the powers of previous powerplants to remove the extra power and use the RealPMin for this powerplant
            AdaptPreviousPowerPlantLoads(previousPowerPlantLoadsList, extraPower);
            return(powerPlantLoad.RealPMin, 0);
        }