package com.docus.server.common.download;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class GeneralDownloadInfo implements IDownloadInfo {

	/**
	 * 0:ftp地址，1:文件，2：用户名：3：密码，4：端口
	 * @param fullUrl
	 * @return
	 */
	public static String[] getHostNameAndFilePath(String fullUrl) {
		fullUrl = fullUrl.trim();
		String[] res = new String[5];
		int beginIndex = "ftp://".length();
		int endIndex = fullUrl.indexOf('/', beginIndex);
		if (endIndex != -1) {
			res[0] = fullUrl.substring(beginIndex, endIndex);
			res[1] = fullUrl.substring(endIndex + 1);
		} else {
			res[0] = fullUrl.substring(beginIndex);
			res[1] = Tools.getRandomUUID().toString() + ".none";
		}
		String[] temp = res[0].split("@");
		if(temp.length>1){
			res[0] = temp[1];
			res[2] =temp[0];
		}
		else
		{
			res[2]="";
			res[3]="";
		}
		temp = res[0].split(":");
		if(temp.length>1){
			res[0] = temp[0];
			res[4] =temp[1];
		}
		else
		{
			res[4]="";
		}
		if(!StringUtils.isEmpty(res[2])){
			temp = res[2].split(":");
			if(temp.length>1){
				res[2] = temp[0];
				res[3] =temp[1];
			}
		}

		return res;
	}

	public GeneralDownloadInfo(RemoteLocalPair pair) {
		this.pair = pair;
		curName = pair.localName;
		curFlagFile = new File(pair.getLocalFullPath()+".flags");
		if (!curFlagFile.getParentFile().exists()) {
			curFlagFile.getParentFile().mkdirs();
		}
	}

	@Override
	public FileCheckPoints getCurCheckPoints() {
		return chp;
	}

	@Override
	public RemoteLocalPair getPair() {
		return this.pair;
	}

	@Override
	public void initDownload() {

	}



	@Override
	public int getSplitNum(){
		return this.pair.splitNum;
	}
	@Override
	public boolean isNeedDownload(FileCheckPoints serverInitChp) {
		chp = readInfo();
		if (chp.timestamp == serverInitChp.timestamp && chp.totalSize == serverInitChp.totalSize && chp.getSplit() == serverInitChp.getSplit()) {
			// 不需要下载
			boolean isneed = false;
			for (int i = 0; i < chp.getStartPos().length; i++) {
				if (chp.getStartPos()[i] < chp.getEndPos()[i]) {
					isneed = true;
					logger.info("restore from checkpoint");
					break;
				}
			}
			return isneed;
		} else {
			chp.copy(serverInitChp);
			return true;
		}
	}

	@Override
	public synchronized boolean  writeInfo(FileCheckPoints chkp) {
		DataOutputStream dos = null;
		try {
			dos = new DataOutputStream(new FileOutputStream(curFlagFile));
			dos.writeLong(chkp.timestamp);
			dos.writeLong(chkp.totalSize);
			int split = chp.getSplit();
			dos.writeInt(split);
			for(int i=0; i < chp.getSplit(); i++){
				dos.writeLong(chp.getStartPos()[i]);
				dos.writeLong(chp.getEndPos()[i]);
			}
		} catch (FileNotFoundException e) {
			logger.debug(curName, e);
		} catch (IOException e) {
			logger.debug(curName, e);
		} finally {
			if (dos != null) {
				try {
					dos.close();
				} catch (IOException e) {
					logger.debug(curName, e);
				}
			}
		}
		return true;
	}

	/**
	 * <b>function:</b>读取写入点的位置信息 如果不存在，那么
	 */
	@Override
	public FileCheckPoints readInfo() {
		if (curFlagFile.exists()) {
			DataInputStream dis = null;
			try {
				dis = new DataInputStream(new FileInputStream(curFlagFile));
				long curTimeStamp = dis.readLong();
				long curTotalSize = dis.readLong();
				int curSplit = dis.readInt();
				FileCheckPoints chkP = new FileCheckPoints();
				chkP.timestamp = curTimeStamp;
				chkP.totalSize = curTotalSize;
				long[] sp = new long[curSplit];
				long[] ep = new long[curSplit];
				for (int i=0; i< curSplit; i++){
					sp[i] = dis.readLong();
					ep[i] = dis.readLong();
				}
				chkP.setStartPos(sp);
				chkP.setEndPos(ep);
				return chkP;
			} catch (FileNotFoundException e) {
				logger.debug(curName, e);
			} catch (IOException e) {
				logger.debug(curName, e);
			} finally {
				if (dis != null) {
					try {
						dis.close();
					} catch (IOException e) {
						logger.debug(curName, e);
					}
				}
			}
		} else {
			return new FileCheckPoints();
		}
		return new FileCheckPoints();
	}

	@Override
	public void downloadDone(FileCheckPoints chkp) {
		writeInfo(chkp);
	}

	
    private Logger logger = LoggerFactory.getLogger(GeneralDownloadInfo.class);

	
	private RemoteLocalPair pair;
	private String curName;
	private File curFlagFile;
	private FileCheckPoints chp = null;

}
