package com.yonge.netty.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

import java.io.FileInputStream;
import java.net.URI;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import com.yonge.netty.handler.WebSocketClientHandler;

public class NettyClient {
	
	public static void main(String[] args) throws Exception {
		NettyClient client = new NettyClient();
		client.connect(new URI("ws://localhost:8090/audioAnalysis/123456"), "654321");
	}

	public void connect(URI websocketURI, String token) throws Exception {
		EventLoopGroup worker = new NioEventLoopGroup();
		try {
			Bootstrap b = new Bootstrap();
			/**
			 *EventLoop的组
			 */
			b.group(worker);
			/**
			 * 用于构造socketchannel工厂
			 */
			b.channel(NioSocketChannel.class);
			/**设置选项
			 * 参数：Socket的标准参数（key，value），可自行百度
			   保持呼吸，不要断气！
			 * */
			b.option(ChannelOption.SO_KEEPALIVE, true);
			
			HttpHeaders httpHeaders = new DefaultHttpHeaders();
			httpHeaders.add("Authorization", token);
            //进行握手
            WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(websocketURI, WebSocketVersion.V13, (String)null, true,httpHeaders);
			
			final WebSocketClientHandler handler = new WebSocketClientHandler(handshaker);
			
			/**
			 * 自定义客户端Handle（客户端在这里搞事情）
			 */
			b.handler(new ChannelInitializer<SocketChannel>() {
				@Override
				public void initChannel(SocketChannel ch) throws Exception {
					ch.pipeline().addLast(new HttpClientCodec());
					ch.pipeline().addLast(new ChunkedWriteHandler());
					ch.pipeline().addLast(new HttpObjectAggregator(1024 * 8));
					ch.pipeline().addLast(new WebSocketServerCompressionHandler());
					//ch.pipeline().addLast(new WebSocketclientProtocolHandler(webSocketPath, "WebSocket", true, 65536 * 1000, false, true))
					ch.pipeline().addLast(handler);
				}
			});
			
			Channel channel = b.connect(websocketURI.getHost(), websocketURI.getPort()).sync().channel();
	        handler.handshakeFuture().sync();
	        
			//step1发送xml
			String step1 = FileUtils.readFileToString(FileUtils.toFile(WebSocketClientHandler.class.getResource("/悬崖上的金鱼姬1 速度160.json")));
			channel.writeAndFlush(new TextWebSocketFrame(step1));
			
			String step2 = "{\"header\":{\"commond\":\"recordStart\",\"type\":\"SOUND_COMPARE\",\"status\":200}}";
			channel.writeAndFlush(new TextWebSocketFrame(step2));
			
			String step3 = "{\"body\":{\"offsetTime\":1302},\"uuid\":\"1657779786620650261\",\"header\":{\"commond\":\"audioPlayStart\",\"type\":\"SOUND_COMPARE\"}}";
			channel.writeAndFlush(new TextWebSocketFrame(step3));
			
			//step4 发送wav
			String fileName = "/悬崖上的金鱼姬1 速度160.wav";
			AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(FileUtils.toFile(WebSocketClientHandler.class.getResource(fileName)));
			
			AudioFormat baseFormat = audioInputStream.getFormat();

			System.out.println(baseFormat.toString());

			byte[] audio = IOUtils.toByteArray(audioInputStream);
			
			channel.writeAndFlush(new BinaryWebSocketFrame(Unpooled.wrappedBuffer(audio)));
			audioInputStream.close();
			
			//step5 结束评测
			String step5 = "{\"header\":{\"commond\":\"recordEnd\",\"type\":\"SOUND_COMPARE\",\"status\":200}}";
			channel.writeAndFlush(new TextWebSocketFrame(step5));
			
			
		} finally {
			//worker.shutdownGracefully();
		}
	}

}
