/*
 * Copyright (C) 2001, C. Ramakrishnan / Illposed Software.
 * All rights reserved.
 *
 * This code is licensed under the BSD 3-Clause license.
 * See file LICENSE (or LICENSE.html) for more information.
 */

package com.illposed.osc;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

public class OSCPortTest extends junit.framework.TestCase {

	private static final long WAIT_FOR_SOCKET_CLOSE = 30;

	private OSCPortOut sender;
	private OSCPortIn  receiver;

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		sender = new OSCPortOut();
		receiver = new OSCPortIn(OSCPort.defaultSCOSCPort());
	}

	@Override
	protected void tearDown() throws Exception {
		receiver.close();
		sender.close();
		// wait a bit after closing the receiver,
		// because (some) operating systems need some time
		// to actually close the underlying socket
		Thread.sleep(WAIT_FOR_SOCKET_CLOSE);
		super.tearDown();
	}

	public void testPorts() throws Exception {

		assertEquals("Bad default SuperCollider OSC port",
				57110, OSCPort.defaultSCOSCPort());
		assertEquals("Bad default SuperCollider Language OSC port",
				57120, OSCPort.defaultSCLangOSCPort());

		assertEquals("Bad default port with ctor()",
				57110, sender.getPort());

		sender.close();
		sender = new OSCPortOut(InetAddress.getLocalHost());
		assertEquals("Bad default port with ctor(address)",
				57110, sender.getPort());

		sender.close();
		sender = new OSCPortOut(InetAddress.getLocalHost(), 12345);
		assertEquals("Bad port with ctor(address, port)",
				12345, sender.getPort());
	}

	public void testStart() throws Exception {
		OSCMessage mesg = new OSCMessage("/sc/stop");
		sender.send(mesg);
	}

	public void testMessageWithArgs() throws Exception {
		List<Object> args = new ArrayList<Object>(2);
		args.add(new Integer(3));
		args.add("hello");
		OSCMessage mesg = new OSCMessage("/foo/bar", args);
		sender.send(mesg);
	}

	public void testBundle() throws Exception {
		List<Object> args = new ArrayList<Object>(2);
		args.add(new Integer(3));
		args.add("hello");
		List<OSCPacket> msgs = new ArrayList<OSCPacket>(1);
		msgs.add(new OSCMessage("/foo/bar", args));
		OSCBundle bundle = new OSCBundle(msgs);
		sender.send(bundle);
	}

	public void testBundle2() throws Exception {
		OSCMessage mesg = new OSCMessage("/foo/bar");
		mesg.addArgument(new Integer(3));
		mesg.addArgument("hello");
		OSCBundle bundle = new OSCBundle();
		bundle.addPacket(mesg);
		sender.send(bundle);
	}

	public void testReceiving() throws Exception {
		OSCMessage mesg = new OSCMessage("/message/receiving");
		TestOSCListener listener = new TestOSCListener();
		receiver.addListener("/message/receiving", listener);
		receiver.startListening();
		sender.send(mesg);
		Thread.sleep(100); // wait a bit
		receiver.stopListening();
		if (!listener.isMessageReceived()) {
			fail("Message was not received");
		}
	}

	public void testBundleReceiving() throws Exception {
		OSCBundle bundle = new OSCBundle();
		bundle.addPacket(new OSCMessage("/bundle/receiving"));
		TestOSCListener listener = new TestOSCListener();
		receiver.addListener("/bundle/receiving", listener);
		receiver.startListening();
		sender.send(bundle);
		Thread.sleep(100); // wait a bit
		receiver.stopListening();
		if (!listener.isMessageReceived()) {
			fail("Message was not received");
		}
		if (!listener.getReceivedTimestamp().equals(bundle.getTimestamp())) {
			fail("Message should have timestamp " + bundle.getTimestamp()
					+ " but has " + listener.getReceivedTimestamp());
		}
	}
}

@@ -945,24 +945,1047 @@
 Down();%0A%09%7D%0A%0A
+%09public void testSocketClose() throws Exception %7B%0A%0A%09%09// close the underlying sockets%0A%09%09receiver.close();%0A%09%09sender.close();%0A%0A%09%09// make sure the old receiver is gone for good%0A%09%09Thread.sleep(WAIT_FOR_SOCKET_CLOSE);%0A%0A%09%09// check if the underlying sockets were closed%0A%09%09// NOTE We can have many (out-)sockets sending%0A%09%09//   on the same address and port,%0A%09%09//   but only one receiving per each such tuple.%0A%09%09sender = new OSCPortOut();%0A%09%09receiver = new OSCPortIn(OSCPort.defaultSCOSCPort());%0A%09%7D%0A%0A%09public void testSocketAutoClose() throws Exception %7B%0A%0A%09%09// DANGEROUS! here we forget to close the underlying sockets!%0A%09%09receiver = null;%0A%09%09sender = null;%0A%0A%09%09// make sure the old receiver is gone for good%0A%09%09System.gc();%0A%09%09Thread.sleep(WAIT_FOR_SOCKET_CLOSE);%0A%0A%09%09// check if the underlying sockets were closed%0A%09%09// NOTE We can have many (out-)sockets sending%0A%09%09//   on the same address and port,%0A%09%09//   but only one receiving per each such tuple.%0A%09%09sender = new OSCPortOut();%0A%09%09receiver = new OSCPortIn(OSCPort.defaultSCOSCPort());%0A%09%7D%0A%0A
 %09public void

add 2 new test that check whether the underlying sockets of OSCPort get closed properly