package com.pronoia.camel.processor;

import com.pronoia.util.RandomInRange;

import org.apache.camel.CamelContext;
import org.apache.camel.EndpointInject;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.hl7.HL7Constants;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

/**
 * Test the behaviour of using the timer component with a very small time window
 *
 * Need to ensure that the timer doesn't overrun the target endpoint if it is a
 * little slow.  If it does, it could cause artificial FIFO issues
 */
public class HL7MessageFactoryWithFastTimerTest extends CamelTestSupport {
  @EndpointInject(uri = "mock://target")
  MockEndpoint target;

  @Override
  protected CamelContext createCamelContext() throws Exception {
    DefaultCamelContext context = (DefaultCamelContext) super.createCamelContext();

    context.setUseMDCLogging(true);
    context.setName(this.getClass().getSimpleName());

    return context;
  }


  @Override
  protected RouteBuilder[] createRouteBuilders() throws Exception {
    RouteBuilder[] builders = new RouteBuilder[2];

    // Create the receiver with a random delay to simulate a slow target
    builders[0] = new RouteBuilder() {
      @Override
      public void configure() throws Exception {
        from("direct://slow-target")
            .delay().method(new RandomInRange(10, 500), "nextDelay")
            .log(LoggingLevel.DEBUG, "ControlId: $simple{property[HL7MessageFactory.MessageControlId]}")
            .to("mock://target")
        ;
      }
    };

    // Create a producer driven by a timer with a very small delay
    builders[1] = new RouteBuilder() {
      @Override
      public void configure() throws Exception {
        from("timer://test-timer?period=1")
            .process(new HL7MessageFactory())
            .to("direct://slow-target")
        ;

      }
    };

    return builders;
  }


  @Test
  public void testNextMessage() throws Exception {
    target.expectedMinimumMessageCount(45);
    target.assertMessagesAscending(header(HL7Constants.HL7_MESSAGE_CONTROL));

    Thread.sleep(15000);

    assertMockEndpointsSatisfied();
  }
}

