/**
 * Created on 30 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.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import jp.himacs.avoidbugs.ipv6.bug6230761.IPv6AddressBean;
import jp.himacs.avoidbugs.ipv6.bug6230761.WinsockIPv6;
import junit.framework.TestCase;

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

	public WinsockIPv6Test(String name) {
		super(name);
	}

	protected void setUp() throws Exception {
		super.setUp();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}

	/**
	 * test if creating a datagram socket will success. 
	 */
	public void testCreateSocket() {
		int fd = WinsockIPv6.createSocket(WinsockIPv6.SOCK_DGRAM, WinsockIPv6.IPPROTO_UDP);
		assertTrue("create socket failed",fd!=-1);
		int result = WinsockIPv6.closesocket(fd);
		assertTrue("close socket failed",result!=-1);
	}

	/**
	 * test if binding will success.
	 */
	public void testBindIntIntByteArray() {
		int fd = WinsockIPv6.createSocket(WinsockIPv6.SOCK_DGRAM, WinsockIPv6.IPPROTO_UDP);
		assertTrue("create socket failed",fd!=-1);
		byte[] addr = new byte[16];
		int result = WinsockIPv6.bind(fd,9999, addr,0);
		assertTrue("bind socket failed",result!=-1);
		result = WinsockIPv6.closesocket(fd);
		assertTrue("close socket failed",result!=-1);
	}

	/**
	 * test if sendto/recvfrom will success.
	 * @throws SocketException unexpected
	 */
	public void testSendRecv() throws SocketException {
		int recvFd = WinsockIPv6.createSocket(WinsockIPv6.SOCK_DGRAM, WinsockIPv6.IPPROTO_UDP);
		assertTrue("create socket failed",recvFd!=-1);
		byte[] addr = new byte[16];
		int result = WinsockIPv6.bind(recvFd,9999, addr,0);
		assertTrue("bind socket failed",result!=-1);
		int sendFd = WinsockIPv6.createSocket(WinsockIPv6.SOCK_DGRAM, WinsockIPv6.IPPROTO_UDP);
		assertTrue("create socket failed",sendFd!=-1);
		
		Enumeration<NetworkInterface> intfs = NetworkInterface.getNetworkInterfaces();
		InetAddress inet = null;
		while(intfs.hasMoreElements()) {
			NetworkInterface intf = intfs.nextElement();
			Enumeration<InetAddress> inets = intf.getInetAddresses();
			while(inets.hasMoreElements()) {
				inet = inets.nextElement();
				if (inet.getAddress().length==16) {
					break;
				}
			}
			if (inet != null) {
				break;
			}
		}
		Inet6Address i6 = (Inet6Address)inet;
		result = WinsockIPv6.sendto(sendFd, 9999, i6.getAddress(), i6.getScopeId(), "abc".getBytes());
		IPv6AddressBean bean = new IPv6AddressBean();
		byte[] data = new byte[3];
		result = WinsockIPv6.recvfrom(recvFd, bean, data);
		assertTrue("recvfrom socket failed",recvFd!=-1);
		assertEquals("recv data is invalid", new String("abc"), new String(data));
		
	}

}
