package com.xixun.communicate;


import com.xixun.display.MyLog;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;

/**
 * Created by Administrator on 16/11/15.
 */
enum ReceFileState {
    NONE, 
    READY, 
    FILE_EXIST,
    SUCCESS
}

public class SendFile{
    private ReceFileState receFileState = ReceFileState.NONE;

    Socket socket=null;
    DataInputStream receStream=null;
    DataOutputStream sendStream=null;

    boolean bReady = false;
    public boolean GetReady() { return bReady; }
	
	private ClientManage clientManage=null;
	private String clientIpAddress=null;
	
	SendFile(ClientManage clientManage,Socket socket)
     {  this.clientManage=clientManage;
		this.socket=socket;

	     clientIpAddress=socket.getInetAddress().getHostAddress();

	     new Thread() {
		     public void run() {
			     Process();
		     }
	     }.start();
     }
     
	private void Process()
	{	try {
			receStream = new DataInputStream(socket.getInputStream());
			sendStream = new DataOutputStream(socket.getOutputStream());
			bReady=true;
		
			while (GetReady() && (NeedExit()==false)) {
				try {
					String fileState = receStream.readUTF();
					//System.out.println("Rece File State: "+ fileState);

					switch (fileState)
                    {
                        case "FileReceReady":
                            receFileState = ReceFileState.READY;
                            break;
                        case "FileExist":
                            receFileState = ReceFileState.FILE_EXIST;
                            break;
                        case "FileReceSuccess":
                            receFileState = ReceFileState.SUCCESS;
                            break;
                        default:
                            receFileState = ReceFileState.NONE;
                            break;
                    }
					
					//System.out.println("Rece File State: "+ fileState + " Value=" +receFileState);
				} catch (Exception e) {
					if (NeedExit()==false || GetReady())
						System.out.println(clientIpAddress+ " " + Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
								+ "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
								+ "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
								+ "    Error:" + e.getMessage() + "\r\n\r\n"
						);
					stop();
					break;
				} finally {
					try {
						Thread.sleep(500);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
				}
			}
		} catch (Exception e) {
			stop();
		}
	}
	
	private boolean WaitCommandAck(int iDelayMs) {
        while (iDelayMs > 0) {
            if (NeedExit()) break;
	        if (GetReady()==false) break;

            if (receFileState != ReceFileState.NONE) return true;
	        try {
		        Thread.sleep(100);
	        } catch (InterruptedException e1) {
		        e1.printStackTrace();
		        break;
	        }
	        iDelayMs -= 100;
        }
        return false;
    }

    public int SendFilePro(String pathFile, String strObjectName) throws IOException {
        int size = -1;
        long fileLength = 0;
	    int iWorkResault = 0;
	    byte[] buffer = new byte[1024];
        FileInputStream fileInputStream = null;
        DataInputStream dataInputStream = null;

        if (NeedExit()) return -1;
	    if (GetReady()==false) return -1;
	    if (sendStream == null) return -1;
	    
	    if (pathFile == null) return 0;
	    if (pathFile.length()<=0)  return -1;
        if (strObjectName == null) return 0;
	    if (strObjectName.length()<=0)  return -1;
	    
	    //System.out.println(clientIpAddress+" Send FileName: \"" + pathFile + ", to File Name ：" + strObjectName);
	    
        File file=new File(pathFile);
        if (file.exists()==false) return -1;



        try {

            synchronized (this) {
                int length = 0;
                fileInputStream = new FileInputStream(pathFile);
                dataInputStream = new DataInputStream(fileInputStream);

                fileLength = new File(pathFile).length();

                receFileState = ReceFileState.NONE;


                sendStream.writeUTF(strObjectName);
                sendStream.flush();
                sendStream.writeLong(fileLength);
                sendStream.flush();

                WaitCommandAck(5000);
                switch (receFileState)
                {   case READY:
                        receFileState = ReceFileState.NONE;
                        while (NeedExit()==false) {
                            if (GetReady()==false) break;
                            if ((length = dataInputStream.read(buffer)) <= 0) break;
                            sendStream.write(buffer, 0, length);
                        }
                        sendStream.flush();
                        if (NeedExit()==false || (GetReady()))
                            WaitCommandAck(5000);
                        if (NeedExit() || (GetReady()==false))
                            MyLog.i(clientIpAddress+ " Need exit,FileName: \"" + pathFile + ", to File Name ：" + strObjectName + " may be sendded!");
                        else if (receFileState == ReceFileState.SUCCESS)
                            MyLog.i(clientIpAddress+" FileName: \"" + pathFile + "\" Lenth: " + fileLength + ", to File Name ：" + strObjectName + " Send Ok!");
                        else
                            MyLog.i(clientIpAddress+" FileName: \"" + pathFile + "\" Lenth: " + fileLength + ", to File Name ：" + strObjectName + " UnknowState:" + receFileState);
                        break;
                    case FILE_EXIST:
                        MyLog.i(clientIpAddress+" FileName: \"" + pathFile + "\" Have Exist,Needn't Send!");
                        break;
                }
            }
        } catch (Exception e) {
            if (NeedExit()==false || GetReady())
                MyLog.i(clientIpAddress+ " "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                    + "Function: " + Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                    + "Line" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
                    + "    Error:" + e.getMessage() + "\r\n\r\n"
            );
	        stop();
            //System.out.println(clientIpAddress+ " FileName: \"" + pathFile + "\" Send Error!");
            iWorkResault = -1;
        } finally {
            try {
            } catch (Exception e1) {
                if (dataInputStream != null) dataInputStream.close();
                if (fileInputStream != null) fileInputStream.close();
            }

        }
        return iWorkResault;
    }
	
	public void stop() {
		//if (GetReady()==false) return;
		try {
			bReady = false;
			
			if (NeedExit()==false)  // 非外部请求造成的退出，需要注销当前显示屏。
				clientManage.Request_Exit();
			
			if (receStream != null) receStream.close();
			if (sendStream != null) sendStream.close();
			if (socket != null) socket.close();
		} catch (Exception e) {	}
		if (NeedExit()==false)
            MyLog.i(clientIpAddress+ " "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
					+   "Function: " +Thread.currentThread().getStackTrace()[2].getMethodName()
			);
	}

    boolean bNeedExit=false;
	public boolean NeedExit() { return bNeedExit; }
    public void Exit()
    {    if (bNeedExit) return;
        bNeedExit=true;
        stop();

        MyLog.i(" "+ Thread.currentThread().getStackTrace()[2].getFileName() + "-->"
                +   "Function: " +Thread.currentThread().getStackTrace()[2].getMethodName() + "-->"
                +   "Line" +Thread.currentThread().getStackTrace()[2].getLineNumber() + ":\r\n"
        );
    }

}