package org.kne.cloud.network.srv6;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

import org.kne.cloud.network.ipv6.IPv6Packet;

public class PacketReorder {
	public PacketReorder(long sequenceNumber) {
		this.sequenceNumber =sequenceNumber;
	}
	private ReentrantLock rlock=new ReentrantLock();
	private List<TcpPacketEntry> tcps=new ArrayList<>();
	private volatile long sequenceNumber;
	public List<TcpPacketEntry> getTcps() {
		return tcps;
	}
	public long getSequenceNumber() {
		return sequenceNumber;
	}
	public static class TcpPacketEntry{
		private IPv6Packet packet;
		private  long sequenceNumber;
		private long addtime=System.nanoTime();
		
		public TcpPacketEntry(IPv6Packet packet, long sequenceNumber) {
			super();
			this.packet = packet;
			this.sequenceNumber = sequenceNumber;
		}
		public IPv6Packet getPacket() {
			return packet;
		}
		public long getAddtime() {
			return addtime;
		}
		public boolean checkTimeOut() {
			return System.nanoTime()-addtime>10000000L;
		}
		public long getSequenceNumber() {
			return sequenceNumber;
		}
		
	}
	public void sortPackets(IPv6Packet pack,long seq, IPv6PacketConsumer packconsumer) throws IOException {
		rlock.lock();
		try {
			//System.out.println("包序号："+seq);
			//System.out.println("当前序号："+sequenceNumber);
			if(seq<sequenceNumber) {
			packconsumer.accept(pack);
			}else {
			loop:	do {
			for(int i=0;i<tcps.size();i++) {
				TcpPacketEntry tpe=tcps.get(i);
				if(seq<tpe.getSequenceNumber()) {
					tcps.add(i, new TcpPacketEntry(pack, seq));
					break loop;
				}
			}
			tcps.add(new TcpPacketEntry(pack, seq));
				}while(false);
			}
			for (Iterator<TcpPacketEntry> iterator = tcps.iterator(); iterator.hasNext();) {
				TcpPacketEntry tcpPacketEntry = (TcpPacketEntry) iterator.next();
				if(tcpPacketEntry.getSequenceNumber()==sequenceNumber) {
					//System.out.println("	排序："+tcpPacketEntry.getSequenceNumber());
					iterator.remove();
					sequenceNumber++;
					packconsumer.accept(pack);
				}else if(tcpPacketEntry.getSequenceNumber()<sequenceNumber) {
					iterator.remove();
					packconsumer.accept(pack);
				}else if(tcpPacketEntry.checkTimeOut()){
					//System.out.println("	超时："+tcpPacketEntry.getSequenceNumber());
					iterator.remove();
					sequenceNumber=tcpPacketEntry.getSequenceNumber()+1;
					packconsumer.accept(pack);
				}
			}
		}finally {
			rlock.unlock();
		}
	}
}
