/**
 * Created on 31 Oct. 2009
 * Created by Takaki Tsue, Masato Kawahashi
 * Copyright (C) 2009 HIMACS,Ltd. 
 * Licensed under the Apache License, Version 2.0
 *
 */
package jp.himacs.avoidbugs.ipv6.bug6230761;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;

import junit.framework.TestCase;

/**
 * JUnit test case for DatagramChannel
 * @author t-tsue
 *
 */
public class DatagramChannelTest extends TestCase {

	/**
	 * @param name
	 */
	public DatagramChannelTest(String name) {
		super(name);
		System.setProperty("java.net.preferIPv6Addresses", "true");
		System.setProperty("java.nio.channels.spi.SelectorProvider", 
				"jp.himacs.avoidbugs.ipv6.bug6230761.SelectorProviderImplIPv6");
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		super.tearDown();
	}

	/**
	 * Test method for {@link java.nio.channels.DatagramChannel#socket()}.
	 * @throws IOException unknown exception 
	 */
	public void testBind() throws IOException {
		DatagramChannel channel = DatagramChannel.open();
        byte[] addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	1};
        InetAddress inetAddr = InetAddress.getByAddress(addr);
        InetSocketAddress addr_9999 = new InetSocketAddress(inetAddr, 9999);
		channel.socket().bind(addr_9999);
		System.out.println("bind success");
		channel.close();
	}

	/**
	 * Test UDP transmission for send "abc" and recv "abc"
	 * @throws IOException unknown exception
	 */
	public void testRecv() throws IOException {
		Selector selector = Selector.open();

		DatagramChannel recvChannel = DatagramChannel.open();
        byte[] addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	1};
        InetAddress inetAddr = InetAddress.getByAddress(addr);
        InetSocketAddress addr_9999 = new InetSocketAddress(inetAddr, 9999);
        InetSocketAddress addr_0000 = new InetSocketAddress(inetAddr, 0);
		recvChannel.socket().bind(addr_9999);
		recvChannel.configureBlocking(false);
		recvChannel.register(selector, SelectionKey.OP_READ);
		DatagramChannel sendChannel = DatagramChannel.open();
		ByteBuffer data = ByteBuffer.wrap("abc".getBytes());
		sendChannel.socket().bind(addr_0000);
		sendChannel.send(data, addr_9999);
		int count =  selector.select();
		assertEquals("count value is invalid",1,count);
		for (Iterator keyIterator = selector.selectedKeys().iterator(); keyIterator.hasNext();)
		{
			SelectionKey key = (SelectionKey) keyIterator.next();
			keyIterator.remove();
			assertTrue("key is invalid",key.isValid());
			assertTrue("key is readable",key.isReadable());
			ByteBuffer recv_buf = ByteBuffer.allocate(2048);
			int length = recvChannel.read(recv_buf);
			assertEquals("invalid length", 3, length);
			byte[] buf = new byte[length];
			recv_buf.flip();
			recv_buf.get(buf);
			assertEquals("recv String is invalid","abc",new String(buf));
		}
	}
}
