package eu.osci.messagetypes;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;

import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Logger;

import org.junit.BeforeClass;
import org.junit.Test;

import eu.osci.messageparts.OSCIFragmentCreator;


/**
 * Test for testing the {@link OSCIMsgBoxStatusListRequest}<br>
 * Tests all different fetch selectors from the OSCIMsgBoxStatusListRequest class and some important header
 * elements. To run this tests an implementation must be installed under the URL declared in the static field
 * MessageParent.URL_MSGBOX_HOST. The installation of the msgBox must provide WSDLs under the URL
 * MessageParent.URL_WSDL_USER, MessageParent.URL_WSDL_Synchron, MessageParent.URL_WSDL_GERNERIC_USER,
 * MessageParent.WSA_REPLY_TO.<br>
 * Copyright © 2010 Freie Hansestadt Bremen. <br>
 * Created by bremen online services Entwicklungs- und Betriebsgesellschaft mbH & Co. KG. <br>
 * This library (Starter Kit) can be used by anybody according to the Bremer Lizenz für freie
 * Softwarebibliotheken. The license terms can be viewed at www.osci.de or can be ordered at the
 * OSCI-Leitstelle (Die Senatorin für Finanzen, Freie Hansestadt Bremen, Postfach 10 15 40, 28015 Bremen).
 * 
 * @author R. Lindemann
 */
public class TestOSCIMsgBoxStatusList extends MessageParent
{

  protected static Logger LOG = Logger.getLogger(TestOSCIMsgBoxStatusList.class.getName());

  private static ArrayList<String> msgIDList = new ArrayList<String>();

  private static ArrayList<String> relatesTo = new ArrayList<String>();

  private static Date startTime = new Date();

  @BeforeClass
  public static void beforeClass() throws Exception
  {
    startTime = new Date();
    relatesTo.add(OSCIFragmentCreator.createUUID());
    relatesTo.add(OSCIFragmentCreator.createUUID());
    OSCIMessage req = MessageParent.sendToMsgBox(OSCIFragmentCreator.createRelatesTo(relatesTo.get(0)), true);
    msgIDList.add(req.getMessageId().getValue());
    req = MessageParent.sendToMsgBox(OSCIFragmentCreator.createRelatesTo(relatesTo.get(0)), true);
    msgIDList.add(req.getMessageId().getValue());
    req = MessageParent.sendToMsgBox(OSCIFragmentCreator.createRelatesTo(relatesTo.get(1)), true);
    msgIDList.add(req.getMessageId().getValue());
  }

  /**
   * Fetches the status lists with no more selection arguments.<br>
   * Expected behaviour: Successful sending of the OSCI message without any exceptions and the correct count
   * of statusLists.
   */
  @Test
  public void testFetchAll() throws Exception
  {
    // ############ single Test
    OSCIMsgBoxStatusListRequest req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE,
                                                                      FETCH_PORT);
    req.setSelectionAll(true, OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER), 100);
    OSCIMsgBoxStatusListResponse rsp = req.sendRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertEquals("Items pending", 0, rsp.getItemsPending());
    assertTrue("Wrong status list count: ", rsp.getMsgStatusList().getMsgAttributes().size() > 3);
    // ############### get next test
    // first fetch the list
    req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE, FETCH_PORT);
    req.setSelectionAll(true, OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER), 1);
    rsp = req.sendRequest();

    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertTrue("Wrong status list count: ", rsp.getItemsPending() > 2);
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
    String firstID = rsp.getMsgStatusList().getMsgAttributes().get(0).getMessageID().getValue();
    // ########## Fetch next message ###########
    OSCIMsgBoxGetNextRequest nextReq = new OSCIMsgBoxGetNextRequest(req);

    rsp = nextReq.sendStatusListRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertTrue("Wrong status list count: ", rsp.getItemsPending() > 2);
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
    assertNotNull("No request iterator.", rsp.getFetchIteratorID());
    assertTrue("No request iterator.", rsp.getFetchIteratorID().length() > 0);
    assertNotSame("MsgId is the same.", rsp.getMsgStatusList()
                                           .getMsgAttributes()
                                           .get(0)
                                           .getMessageID()
                                           .getValue(), firstID);
    // ##########now sending the close msg. ################
    OSCIMsgBoxCloseRequest close = new OSCIMsgBoxCloseRequest(nextReq);
    close.sendRequest();
  }

  /**
   * Fetches the status lists with the selection by creation time. <br>
   * Expected behaviour: Successful sending of the OSCI message without any exceptions and the correct count
   * of statusLists.
   */
  @Test
  public void testByDate() throws Exception
  {
    // ######################### first test fetch all #################
    OSCIMsgBoxStatusListRequest req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE,
                                                                      FETCH_PORT);
    req.setSelectionByDate(startTime,
                           new Date(),
                           true,
                           OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER),
                           100);
    OSCIMsgBoxStatusListResponse rsp = req.sendRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertEquals("Wrong items pending", 0, rsp.getItemsPending());
    assertEquals("Wrong status list count: ", 3, rsp.getMsgStatusList().getMsgAttributes().size());
    // ########################### try with fetch next #####################
    // first fetch the list
    req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE, FETCH_PORT);
    req.setSelectionByDate(startTime,
                           new Date(),
                           true,
                           OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER),
                           1);
    rsp = req.sendRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
    assertTrue("Wrong status list count: ", rsp.getItemsPending() > 1);
    String firstID = rsp.getMsgStatusList().getMsgAttributes().get(0).getMessageID().getValue();
    // ########## Fetch next message ###########
    OSCIMsgBoxGetNextRequest nextReq = new OSCIMsgBoxGetNextRequest(req);

    rsp = nextReq.sendStatusListRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertTrue("Wrong status list count: ", rsp.getItemsPending() > 0);
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
    assertNotNull("No request iterator.", rsp.getFetchIteratorID());
    assertTrue("No request iterator.", rsp.getFetchIteratorID().length() > 0);
    assertNotSame("MsgId is the same.", rsp.getMsgStatusList()
                                           .getMsgAttributes()
                                           .get(0)
                                           .getMessageID()
                                           .getValue(), firstID);
    // ##########now sending the close msg. ################
    OSCIMsgBoxCloseRequest close = new OSCIMsgBoxCloseRequest(nextReq);
    close.sendRequest();
  }

  /**
   * Test the limitation of the status list length.<br>
   * Expected behaviour: Successful sending of the OSCI message without any exceptions and the correct count
   * of statusLists.
   */
  @Test
  public void testLimit() throws Exception
  {
    OSCIMsgBoxStatusListRequest req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE,
                                                                      FETCH_PORT);
    req.setSelectionByDate(startTime,
                           new Date(),
                           true,
                           OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER),
                           1);
    OSCIMsgBoxStatusListResponse rsp = req.sendRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertEquals("Wrong items pending", 2, rsp.getItemsPending());
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
  }

  /**
   * Fetches the status lists with the given messageId.<br>
   * Expected behaviour: Successful sending of the OSCI message without any exceptions and the correct count
   * of statusLists.
   */
  // TODO > Version 1.0 Test multi messageIds
  @Test
  public void testMessageId() throws Exception
  {
    OSCIMsgBoxStatusListRequest req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE,
                                                                      FETCH_PORT);
    req.setSelectionByMessageId(new String[]{msgIDList.get(0)},
                                OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER),
                                100);
    OSCIMsgBoxStatusListResponse rsp = req.sendRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertEquals("Wrong items pending", 0, rsp.getItemsPending());
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
  }

  /**
   * Fetches the status lists with the configured RelatesTo parameter.<br>
   * Expected behaviour: Successful sending of the OSCI message without any exceptions and the correct count
   * of statusLists.
   */
  // TODO > Version 1.0 hier sollte noch eine liste von relates to angefordert werden
  @Test
  public void testRelatesTo() throws Exception
  {
    OSCIMsgBoxStatusListRequest req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE,
                                                                      FETCH_PORT);
    req.setSelectionByRelatesTo(new String[]{relatesTo.get(0)},
                                OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER),
                                100);
    OSCIMsgBoxStatusListResponse rsp = req.sendRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertEquals("Wrong items pending", 0, rsp.getItemsPending());
    assertEquals("Wrong status list count: ", 2, rsp.getMsgStatusList().getMsgAttributes().size());

    req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE, FETCH_PORT);
    req.setSelectionByRelatesTo(new String[]{relatesTo.get(1)},
                                OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER),
                                100);
    rsp = req.sendRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
    // ############ multi relatesTo ########################
    // not supported by the server yet
    // req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE, FETCH_PORT);
    // req.setSelectionByRelatesTo(new String[]{relatesTo.get(1),relatesTo.get(1)},
    // OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER),
    // 100);
    // rsp = req.sendRequest();
    // assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    // assertEquals("Wrong status list count: ", 2, rsp.getMsgStatusList().getMsgAttributes().size());
    // ################## get next test ##################
    req = new OSCIMsgBoxStatusListRequest(new URL(URL_WSDL_USER), SERVICE, FETCH_PORT);
    req.setSelectionByRelatesTo(new String[]{relatesTo.get(1)},
                                OSCIFragmentCreator.createEndpointRef(URL_WSDL_USER),
                                1);
    rsp = req.sendRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
    // ########## Fetch next message ###########
    OSCIMsgBoxGetNextRequest nextReq = new OSCIMsgBoxGetNextRequest(req);

    rsp = nextReq.sendStatusListRequest();
    assertFalse("No message found for selection", rsp.noMessageFoundForSelection());
    assertTrue("Wrong status list count: ", rsp.getItemsPending() == 0);
    assertEquals("Wrong status list count: ", 1, rsp.getMsgStatusList().getMsgAttributes().size());
    assertNotNull("No request iterator.", rsp.getFetchIteratorID());
    assertTrue("No request iterator.", rsp.getFetchIteratorID().length() > 0);
    // ##########now sending the close msg. ################
    OSCIMsgBoxCloseRequest close = new OSCIMsgBoxCloseRequest(nextReq);
    close.sendRequest();
  }
}
