package com.itant.filetransfer;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.widget.Toast;

/**
 * 文件接收者(搜索连接热点，下方显示收到的应用)
 * 
 * @author 詹子聪
 *
 */
public class ReceiverActivity extends Activity {

	// 10秒扫描一次
	private static final int WAIT_FOR_SCAN_RESULT = 5 * 1000;
	// 20秒之内没有得到扫描结果就不要再扫描了
	private static final int WIFI_SCAN_TIMEOUT = 200 * 1000;
	
	private static final int CONNECT_SERVER_SUC = 1;
	private Socket mClientSocket;
	
	private WifiManager mWifiManager;
	private Handler mConnectHotSpotHandler = new Handler(new Callback() {

		@Override
		public boolean handleMessage(Message msg) {
			switch (msg.what) {
			case CONNECT_SERVER_SUC:
				Toast.makeText(ReceiverActivity.this, "连接热点成功", Toast.LENGTH_SHORT).show();
				// WiFi连接成功，开socket客户端去连接服务器以接收文件
				final String serverIP = NetworkTools.getSenderIP(mWifiManager);
				new Thread(new Runnable() {
					
					@Override
					public void run() {
						connectTCPServer(serverIP);
					}
				}).start();
				break;

			default:
				Toast.makeText(ReceiverActivity.this, "连接热点失败", Toast.LENGTH_SHORT).show();
				break;
			}
			return true;
		}
	});

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_receiver);

		mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		// 搜索并连接我们APP创建的热点
		new ConnectTask().execute();
	}

	/**
	 * 后台搜索并连接热点
	 * @author 詹子聪
	 */
	private class ConnectTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			// TODO Auto-generated method stub
			connectToHotSpot("12345678", NetworkTools.TYPE_WPA);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
		}
	}

	/**
	 * 连接特定热点
	 * @param ssid 热点名称
	 * @param passwd 密码
	 */
	private void connectToHotSpot(String passwd, int type) {
		// 关闭热点
		NetworkTools.setWifiApEnabled(mWifiManager, null, false);
		
		// 打开WiFi
		if (!mWifiManager.isWifiEnabled()) {
			mWifiManager.setWifiEnabled(true);
		}

		List<ScanResult> scanResults = mWifiManager.getScanResults();
		if (scanResults == null) {
			// 如果没有可用的扫描结果，激活扫描
			mWifiManager.startScan();
			boolean isScanResultIsAvailable = false;
			long startTime = System.currentTimeMillis();
			while (!isScanResultIsAvailable) {
				if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) {
					// 20秒之内还没搜到可用热点就不要再搜了
					return;
				}

				// 等待扫描结果，等5秒之后查看结果
				synchronized (this) {
					try {
						this.wait(WAIT_FOR_SCAN_RESULT);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					if ((mWifiManager.getScanResults() == null)
							|| (mWifiManager.getScanResults().size() <= 0)) {
						continue;
					}
					isScanResultIsAvailable = true;
				}
			}
		}

		// 获取扫描结果(代码能走到这里一定有结果了)
		scanResults = mWifiManager.getScanResults();
		for (ScanResult scanResult : scanResults) {
			// 如果当前这个热点是我们想要连接的热点，那么就连接它
			if (scanResult.SSID.startsWith("backup")) {
				final String ssid = "\"" + scanResult.SSID + "\"";
				WifiConfiguration wifiConfiguration = NetworkTools
						.createWifiInfo(ssid, passwd, type);
				int networkId = mWifiManager.addNetwork(wifiConfiguration);
				// 连接特定热点，并断开其他连接
				mWifiManager.enableNetwork(networkId, true);
				mWifiManager.saveConfiguration();
				mWifiManager.reconnect();
				// 开一个线程去轮询连接情况
				new Thread(new Runnable() {
					
					@Override
					public void run() {
						while (true) {
							if (NetworkTools.isWiFiConnected(ReceiverActivity.this)) {
								// 已经连接上的热点真的是我们想要连接的热点
								if (TextUtils.equals(ssid, NetworkTools.getConnectWifiSsid(mWifiManager))) {
									mConnectHotSpotHandler.sendEmptyMessage(CONNECT_SERVER_SUC);
									break;
								}
							}
							
							// 割两秒去查一下是否已经连上了WiFi
							try {
								Thread.sleep(2000);
							} catch (Exception e) {
								// TODO: handle exception
							}
						}
					}
				}).start();
				return;
			}
		}
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (mClientSocket != null) {
			try {
				mClientSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 连接服务器，从服务器接收应用
	 * @param serverIP
	 */
	private void connectTCPServer(String serverIP) {
        Socket socket = null;
        while (socket == null) {
            try {
                socket = new Socket(serverIP, 8688);
                mClientSocket = socket;
            } catch (IOException e) {
                SystemClock.sleep(1000);
                System.out.println("connect tcp server failed, retry...");
            }
        }

        try {
            // 接收服务器端的消息和文件
        	String destPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "apks" + File.separator;
			File destFileDir = new File(destPath);
			if (!destFileDir.exists()) {
				destFileDir.mkdirs();
			}
			
			try {
				
				DataInputStream inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));  
				// 不断地监听，看服务器是否有东西过来
				while (!ReceiverActivity.this.isFinishing()) {
		            String fileName = inputStream.readUTF();
		            if (!TextUtils.isEmpty(fileName)) {
		            	long fileSize = inputStream.readLong();
			            File destFile = new File(destPath + fileName);
			            
			            DataOutputStream outputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(destFile)));
			            
			            /*byte buf[] = new byte[1024];
				        while ((fileSize / 1024) > 0) {
				        	inputStream.read(buf);
				        	outputStream.write(buf, 0, 1024);
				        	
				        	fileSize -= 1024;
						}
				        
				        int restLen = (int)(fileSize % 1024);
				        inputStream.read(buf, 0, restLen);
				        outputStream.write(buf, 0, restLen);*/
			            
			            byte[] buffer = new byte[(int)fileSize]; 
		                int nIdx = 0; 
		                int nTotalLen = buffer.length; 
		                int nReadLen = 0; 
		                
		                while (nIdx < nTotalLen) 
		                { 
		                	// 从nIdx开始，想读nTotalLen - nIdx那么多，实际上这次读了nReadLen
		                    nReadLen = inputStream.read(buffer, nIdx, nTotalLen - nIdx); 
		                    
		                    if (nReadLen > 0) 
		                    { 
		                    	outputStream.write(buffer, nIdx, nReadLen);
		                        nIdx = nIdx + nReadLen; 
		                    } 
		                    else 
		                    { 
		                        break; 
		                    } 
		                }
				        
				        outputStream.close();
		            }
				}
			} catch (Exception e) {  
	            e.printStackTrace();  
	        }
        	
            System.out.println("quit...");
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
