/*
   * (non-Javadoc)
   *
   * @see WorkflowStep#invoke(WorkflowContext)
   */
  @Override
  public WorkflowContext invoke(WorkflowContext context) {
    LOGGER.info("AgrFlexOfferStub: started");
    List<FlexOfferDto> outputFlexOffers = new ArrayList<>();

    @SuppressWarnings("unchecked")
    List<FlexRequestDto> inputFlexRequests =
        (List<FlexRequestDto>)
            context.getValue(
                FlexOfferDetermineFlexibilityStepParameter.IN.FLEX_REQUEST_DTO_LIST.name());

    /*
     * For each give flex request, choose to: - create an offer, - do not create offer at all, - do not create offer now.
     */
    int decision;
    for (FlexRequestDto flexRequestDto : inputFlexRequests) {
      decision = 1; // original: RANDOM.nextInt(3); // 0,1 or 2
      FlexOfferDto flexOfferDto = new FlexOfferDto();
      flexOfferDto.setFlexRequestSequenceNumber(flexRequestDto.getSequenceNumber());
      flexOfferDto.setExpirationDateTime(
          now.plusDays(FLEX_OFFER_EXPIRATION_DAYS).withTime(0, 0, 0, 0));
      if (decision == 0) {
        // create a flex offer for the flex request: put a populated flex offer.
        LOGGER.debug(
            "A new FlexOffer will be created for FlexRequest with sequence [{}]",
            flexRequestDto.getSequenceNumber());
        populateFlexOfferDto(flexOfferDto, flexRequestDto, true);
        outputFlexOffers.add(flexOfferDto);
      } else if (decision == 1) {
        // refuse to create an offer for the flex request: put an empty flex offer.
        LOGGER.debug(
            "An empty FlexOffer will be created for FlexRequest with sequence [{}]",
            flexRequestDto.getSequenceNumber());
        populateFlexOfferDto(flexOfferDto, flexRequestDto, false);
        outputFlexOffers.add(flexOfferDto);
      } else {
        // do not create a flex offer now: don't put anything new in the output list.
        LOGGER.debug(
            "No FlexOffer will be created now for FlexRequest with sequence [{}]",
            flexRequestDto.getSequenceNumber());
      }
    }
    context.setValue(
        FlexOfferDetermineFlexibilityStepParameter.OUT.FLEX_OFFER_DTO_LIST.name(),
        outputFlexOffers);
    LOGGER.info("AgrFlexOfferStub: complete");
    return context;
  }
 private void populateFlexOfferDto(
     FlexOfferDto flexOfferDto, FlexRequestDto flexRequestDto, boolean populatePtus) {
   flexOfferDto.setPeriod(flexRequestDto.getPeriod());
   flexOfferDto.setConnectionGroupEntityAddress(flexRequestDto.getConnectionGroupEntityAddress());
   flexOfferDto.setParticipantDomain(flexRequestDto.getParticipantDomain());
   if (populatePtus) {
     flexRequestDto
         .getPtus()
         .stream()
         .forEach(
             ptuFlexRequestDto -> {
               PtuFlexOfferDto ptuFlexOfferDto = new PtuFlexOfferDto();
               ptuFlexOfferDto.setPtuIndex(ptuFlexRequestDto.getPtuIndex());
               if (ptuFlexRequestDto.getDisposition() == DispositionTypeDto.AVAILABLE) {
                 ptuFlexOfferDto.setPrice(BigDecimal.ZERO);
                 ptuFlexOfferDto.setPower(BigInteger.ZERO);
               } else {
                 max100PercentOfOriginalPower(ptuFlexRequestDto, ptuFlexOfferDto);
               }
               flexOfferDto.getPtus().add(ptuFlexOfferDto);
             });
   }
 }
 /**
  * Transforms a {@link PlanboardMessage} to a {@link FlexOfferDto}.
  *
  * @param offer
  * @return
  */
 public static FlexOfferDto transform(PlanboardMessage offer) {
   if (offer == null) {
     return null;
   }
   FlexOfferDto flexOfferDto = new FlexOfferDto();
   flexOfferDto.setPeriod(offer.getPeriod());
   flexOfferDto.setParticipantDomain(offer.getParticipantDomain());
   flexOfferDto.setConnectionGroupEntityAddress(offer.getConnectionGroup().getUsefIdentifier());
   flexOfferDto.setSequenceNumber(offer.getSequence());
   flexOfferDto.setFlexRequestSequenceNumber(offer.getOriginSequence());
   flexOfferDto.setExpirationDateTime(offer.getExpirationDate());
   return flexOfferDto;
 }
 /**
  * Transforms a complete list of {@link PtuFlexOffer} to a {@link FlexOfferDto}.
  *
  * @param ptuFlexOffers a {@link java.util.List} of {@link PtuFlexOffer}.
  * @return a {@link FlexOfferDto}.
  */
 public static FlexOfferDto transformPtuFlexOffers(List<PtuFlexOffer> ptuFlexOffers) {
   if (ptuFlexOffers == null || ptuFlexOffers.isEmpty()) {
     return null;
   }
   PtuFlexOffer firstPtuFlexOffer = ptuFlexOffers.get(0);
   FlexOfferDto flexOfferDto = new FlexOfferDto();
   flexOfferDto.setParticipantDomain(firstPtuFlexOffer.getParticipantDomain());
   flexOfferDto.setConnectionGroupEntityAddress(
       firstPtuFlexOffer.getConnectionGroup().getUsefIdentifier());
   flexOfferDto.setPeriod(firstPtuFlexOffer.getPtuContainer().getPtuDate());
   flexOfferDto.setFlexRequestSequenceNumber(firstPtuFlexOffer.getFlexRequestSequence());
   flexOfferDto.setSequenceNumber(firstPtuFlexOffer.getSequence());
   ptuFlexOffers
       .stream()
       .forEach(ptuFlexOffer -> flexOfferDto.getPtus().add(transformPtuFlexOffer(ptuFlexOffer)));
   return flexOfferDto;
 }