/*
 * Copyright 2007 nori090
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jimmy;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

import jimmy.command.Command;
import jimmy.command.Command01;
import jimmy.command.Command02;
import jimmy.command.Command03;
import jimmy.command.Command13;
import jimmy.command.Command02.LinkType;
import junit.framework.TestCase;

import org.apache.commons.codec.binary.Hex;

/**
 * @author nori090
 * @version $Rev: 17 $ $Date: 2008-03-25 22:45:24 +0900 (Tue, 25 Mar 2008) $
 */
public class ConnectionTest
    extends TestCase {
    private Connection create() {
        Connection con = null;
        for ( String s : nodes ) {
            try {
                Node n = new Node( s );
                con = new Connection();
                con.connect( InetAddress.getByName( n.getAddress() ), n.getPort() );
                System.out.println( s );
                break;
            }
            catch ( Exception e ) {
            }
        }
        return con;
    }

    public void test() {
        try {
            Thread t = new Thread( new Srv() );
            t.start();
            Connection con = create();
            Command c = null;
            while ( ( c = con.receiveOneCommand() ) != null ) {
                String cname = c.getClass().getSimpleName();
                if ( cname.equals( "Command01" ) ) {
                    Command01 c01 = (Command01) c;
                    System.out.println( "cmd01:接続先転送速度:" + c01.getSpeed() );
                }
                else if ( cname.equals( "Command02" ) ) {
                    Command02 c02 = (Command02) c;
                    System.out.println( "cmd02:接続タイプ:" + c02.getType() );
                    System.out.println( "cmd02:ポート0接続か:" + c02.isPort0() );
                    System.out.println( "cmd02:諸事情によりポート0接続か:" + c02.isBadPort0() );
                    System.out.println( "cmd02:BBS接続か:" + c02.isBbsLink() );
                }
                else if ( cname.equals( "Command03" ) ) {
                    Command03 c03 = (Command03) c;
                    System.out.println( "cmd03:address:" + c03.getAddress().getHostAddress() );
                    System.out.println( "cmd03:port:" + c03.getListen_port() );
                    System.out.println( "cmd03:ddns:" + c03.getDdns_name() );
                    System.out.println( "cmd03:クラスタキー:" + Arrays.toString( c03.getClustering_key() ) );
                    break;
                }
            }
            Command01 c01 = new Command01();
            c01.setSpeed( (float) 120.0 );
            Command02 c02 = new Command02();
            c02.setBadPort0( false );
            c02.setBbsLink( false );
            c02.setPort0( false );
            c02.setType( LinkType.SEARCH );
            Command03 c03 = new Command03();
            c03.setAddress( InetAddress.getLocalHost() );
            c03.setClustering_key( new String[] { "", "", "" } );
            c03.setDdns_name( "" );
            c03.setListen_port( 7888 );
            con.send( c01.pack() );
            con.send( c02.pack() );
            con.send( c03.pack() );
            int i = 0;
            while ( true ) {
                try {
                    Thread.sleep( 1000 );
                    i++;
                    if ( ( c = con.receiveOneCommand() ) != null ) {
                        String cname = c.getClass().getSimpleName();
                        System.out.println( "きたこれ:" + cname );
                        unpackCommand( c );
                    }
                }
                catch ( Exception e ) {
                    if ( i > 1000 ) {
                        break;
                    }
                }
            }
            con.close();
        }
        catch ( Exception e ) {
            e.printStackTrace();
            fail( e.getLocalizedMessage() );
        }
    }

    private void unpackCommand( Command c ) {
        if ( c instanceof Command13 ) {
            Command13 c13 = (Command13) c;
            System.out.println( "keyword:" + c13.getKeyword() );
            if ( c13.getNodes() != null ) {
                for ( Node n : c13.getNodes() ) {
                    System.out.println( "node:" + n.getAddress() + ":" + n.getPort() );
                }
            }
            if ( c13.getQueries() != null ) {
                for ( Query q : c13.getQueries() ) {
                    System.out.println( "query:" + q.getSharing_address() + "/" + q.getFile_name() );
                }
            }
        }
    }

    private static class Srv
        implements Runnable {

        @Override
        public void run() {
            try {
                ServerSocket s = new ServerSocket( 7888 );
                Socket sock = s.accept();
                SocketChannel channel = sock.getChannel();
                ByteBuffer buf = ByteBuffer.allocate( 1024 );
                while ( channel.read( buf ) != -1 ) {
                    System.out.println( Hex.encodeHex( buf.array() ) );
                }
            }
            catch ( IOException e ) {
                e.printStackTrace();
            }
        }
    }

    private static final String[] nodes =
        { "@faa414a9f401d4180120f19b31725e9ca5853dff80", "@c004909eac68cf52e1946709495c572a9322c5cb",
            "@e983ac812b1c05a4157a9c9c390e89a877d4a8ce5b", "@9a7015fbd71329768cb5c3aac70f9929436aec",
            "@fc2598d272c23ed7dbfaa550585b6f96d3bcad97ed", "@266ec5655477ce51c91f36040384c1949c005c532763",
            "@d1a46b230e206d97825f0e19d01be6cc4b40d53d", "@c6bfb28f1e47e4835eb92327572cff55497c2980",
            "@c7c61ea9ce765642c3cc4faa266068aeb9255996", "@f6c2c62be9ba1d29c18bfb590bac2b37cc14fbd62d",
            "@ba9680a283c4c9ec9cd5d3d81c71495f1d89f4da", "@cc0c95c71035156e43897cc6f7c61340850541b5",
            "@3de40adb2db4adb4d4149753d31fbf3293", "@3c1e049de7df41c8315df6711be5e7dc2bf00bb1b8f2",
            "@f6c1c629e9ba1837dd88ff4217ae2839c41ff3d62d", "@f77294bd760d9e3c8b38c10c02c34c52f69cd07e0a",
            "@3b5aae85ff1d5bba882995767b0e6067e42e78f098de", "@0a3cc74c3016518a6d0c58a3be19713ec338c4d716",
            "@f3f2e1ea6755e3e90a2cfe932ea3465cb6af596cfa", "@cd6246025de1b82089ece5b2c15e72edd2864c14",
            "@a2c897420d1fd80b7f5f737ff07e5ca88213ef", "@9a7717e0ca17376e8da2dfabc3049220476ce7",
            "@ce58d70f6eff1bf598ecd731cb82c4142613069d", "@dd1cee341ee75eb5f9c7ee549ac25a3c0ea0f7f7",
            "@9e244e9bc770a0391d682de1ca329a2e3b63d6", "@b64dc56d6b7969a014b222033bf677d69427b861",
            "@faa717a1f401d61b0120f09131765591ad8538fb87", "@daa557179f25782cf2ac496fae4ad8360abcf027",
            "@05b62e564e1d95d9420cb4009bf8737734afedee90", "@2059fd7adc26e4693d6beed0037acb23cdc42a4ed2e8",
            "@f524c615357e4cf62d91e4df80cc0887a1c03606ec", "@efcf0d7ee1b1db25fad4bd8040b49069204bfdb764",
            "@917b46d2ed775389d78f216f522e8a3606f978", "@a95841ab4287a21f134b2de93db2988cbb0658",
            "@be2344cf5b32feedd7eaa0593302c2325f2b4868", };

}
