package org.kne.cloud.network.srv6;

import java.io.IOException;
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.jctools.counters.FixedSizeStripedLongCounter;
import org.kne.cloud.clock.HighAccuracyClock;
import org.kne.cloud.network.congestion.MessageBatcher;
import org.kne.cloud.network.ipv6.ControlledIPv6NetworkLink;
import org.kne.cloud.network.ipv6.ICMPv6PostcardPacket;
import org.kne.cloud.network.ipv6.ICMPv6TimeExceededPacket;
import org.kne.cloud.network.ipv6.IPv6Address;
import org.kne.cloud.network.ipv6.IPv6HopByHopTLV;
import org.kne.cloud.network.ipv6.IPv6LinkStateListener;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6HopByHopHeader;
import org.kne.cloud.network.ipv6.IPv6Packet.IPv6SegmentRoutingHeader;
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
import org.kne.cloud.network.ipv6.KLALBOAMHopByHopTLV;
import org.kne.cloud.network.ipv6.KLALBPassportHopByHopTLV;
import org.kne.cloud.network.ipv6.LoopbackIPv6NetworkLink;
import org.kne.cloud.network.ipv6.Neighbor;
import org.kne.cloud.network.ipv6.PadNHopByHopTLV;
import org.kne.cloud.network.ipv6.PostcardEntry;
import org.kne.cloud.network.ipv6.RouteItem;
import org.kne.cloud.network.klalb.KLALBRemoteLink;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.klalb.PerformanceStrategy;
import org.kne.cloud.network.klalb.ui.PerformanceStrategyItem;
import org.kne.concurrent.HighPerformanceExecutor2;
import org.kne.concurrent.TimeoutConcurrentHashMap;
import org.pcap4j.packet.IllegalRawDataException;

import com.google.gson.internal.Pair;

// SRv6路由器主类，实现IPv6段路由功能
public class SRv6Router {
	private static final boolean debug = false; // 调试模式开关

	// public static final int MTU = 16384;
	public static final int MTU = 16384; // 最大传输单元
	public static final int MAX_REROUTE_COUNT = 2;// 1 // 最大重路由次数

	private static final int IPv6_BITS = 128; // IPv6地址位数

	private PerformanceStrategy performanceStrategy=PerformanceStrategy.MULTI_FILL;

	/*private TimeoutConcurrentHashMap<FlowSession, PacketIDGenerator> flowIDmap = new TimeoutConcurrentHashMap<FlowSession, PacketIDGenerator>(
			60000000000L);
*/
	private Set<UUID> unduplicateSet = Collections
			.newSetFromMap(new TimeoutConcurrentHashMap<UUID, Boolean>(3000000000L, 1024, 0.5f));

	private HighAccuracyClock clock;

	// 获取环回地址 ::1
	private static Inet6Address getLoopbackAddress() {
		try {
			return (Inet6Address) Inet6Address.getByName("::1");
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 获取任意本地地址 ::0
	private static Inet6Address getAnyLocalAddress() {
		try {
			return (Inet6Address) Inet6Address.getByName("::0");
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return null;
	}

	private List<RouteItem> routeTabel = new ArrayList<>(); // 路由表

	private List<IPv6NetworkLink> linkTabel = new CopyOnWriteArrayList<>(); // 网络链路表，线程安全

	public List<IPv6NetworkLink> getLinkTabel() {
		return linkTabel;
	}

	// 环回网络链路
	private final LoopbackIPv6NetworkLink inLoopBack;

	// 获取路由表
	public List<RouteItem> getRouteTabel() {
		return routeTabel;
	}

	// 获取当前路由表
	public List<RouteItem> getCurrentRouteTabel() {
		return routeTable0;
	}

	// 默认重路由处理器
	private Consumer<IPv6Packet> defaultReroute = new Consumer<IPv6Packet>() {

		@Override
		public void accept(IPv6Packet t) {
			// HighPerformanceExecutor.defaultExecutor.execute(() -> {
			routePacket(null, t, true); // 执行重路由
			// });
		}
	};

	private boolean unduplicate(IPv6Packet pack) {
		IPv6HopByHopHeader hbh = pack.getHopByHopHeader();
		KLALBOAMHopByHopTLV oamtlv = null;
		if (hbh != null) {
			List<IPv6HopByHopTLV> tlvs = hbh.getTlvs();

			for (IPv6HopByHopTLV tlv : tlvs) {
				if (tlv instanceof KLALBOAMHopByHopTLV) {
					oamtlv = (KLALBOAMHopByHopTLV) tlv;
					break;
				}
			}
		}
		if (oamtlv == null)
			return true;
		boolean bool = unduplicateSet.add(oamtlv.getUUID());
		// System.out.println(bool);
		return bool;
	}
	// 默认接收处理器
	/*
	 * private BiConsumer<IPv6NetworkLink,IPv6Packet> defaultReceive = new
	 * BiConsumer<IPv6NetworkLink,IPv6Packet>() {
	 * 
	 * @Override public void accept(IPv6NetworkLink link,IPv6Packet t) { //
	 * HighPerformanceExecutor.defaultExecutor.execute(() -> { if(unduplicate(t)) {
	 * routePacket(t); // 执行路由 t.putTimePassport("routed"); // 标记路由时间点 } // }); } };
	 */

	// SRH接收处理器
	private BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>> srhReceive = new BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>>() {

		@Override
		public void accept(IPv6NetworkLink link, Supplier<IPv6Packet> pack) {
			enqueuePacketReceiveTask(link, pack);
		}

	};

	public void setPerformanceStrategy(PerformanceStrategy performanceStrategy) {
		this.performanceStrategy=performanceStrategy;
	}

	public PerformanceStrategy getPerformanceStrategy(){
		return performanceStrategy;
	}

	// 链路状态监听器实现
	private class LinkListener implements IPv6LinkStateListener {

		@Override
		public void onOnlineStateUpdate(IPv6NetworkLink link) {
			srListeners.forEach((v) -> {
				v.onLinkChanged(SRv6Router.this, link);
			}); // 通知所有监听器链路状态变化
		}

		@Override
		public void onAddressUpdate(IPv6NetworkLink link) {
			srListeners.forEach((v) -> {
				v.onLinkChanged(SRv6Router.this, link);
			}); // 通知所有监听器地址更新
		}

		@Override
		public void onLocatorUpdate(IPv6NetworkLink link) {
			srListeners.forEach((v) -> {
				v.onLinkChanged(SRv6Router.this, link);
			}); // 通知所有监听器定位器更新
		}

	}

	private IPv6LinkStateListener listener = new LinkListener(); // 链路状态监听器实例

	private Set<SRv6RouterListener> srListeners = new CopyOnWriteArraySet<SRv6RouterListener>(); // SRv6路由器监听器集合

	// 添加SRv6路由器监听器
	public void addSRv6RouterListener(SRv6RouterListener listener) {
		srListeners.add(listener);
	}

	// 移除SRv6路由器监听器
	public void removeSRv6RouterListener(SRv6RouterListener listener) {
		srListeners.remove(listener);
	}
	public void sortRouteTabel() {

		// 构建前缀长度索引的路由表
		List<Map<IPv6Address, List<RouteItem>>> routeTabel1x = new ArrayList<Map<IPv6Address, List<RouteItem>>>(
				IPv6_BITS + 1);
		for (int i = 0; i < IPv6_BITS + 1; i++) {
			routeTabel1x.add(new HashMap<IPv6Address, List<RouteItem>>(1024, 0.5f));
		}
		List<RouteItem> routeTabel0x=routeTable0;
		// 按前缀长度组织路由表
		for (RouteItem item : routeTabel0x) {
			IPv6AddressGroup iag = item.getDestination();
			Map<IPv6Address, List<RouteItem>> map = routeTabel1x.get(iag.getPrefixLength());
			List<RouteItem> newlist = new ArrayList<RouteItem>();
			List<RouteItem> oldlist = map.putIfAbsent(iag.getAddress(), newlist);
			if (oldlist == null) {
				oldlist = newlist;
			}
			oldlist.add(item);
		}
		for(Map<IPv6Address, List<RouteItem>> map:routeTabel1x) {
			for(List<RouteItem>v:map.values()) {
				Collections.sort(v);
			}
		}
		// System.out.println(routeTabel1x);
		routeTabel1 = routeTabel1x; // 更新索引路由表
		
		
	}
	// 更新路由表
	public void updateRouteTabel() {
		List<RouteItem> routeTabel0x = new ArrayList<>();

		// 遍历所有网络链路，收集路由信息
		for (Iterator<IPv6NetworkLink> iterator = linkTabel.iterator(); iterator.hasNext();) {
			IPv6NetworkLink nlink = (IPv6NetworkLink) iterator.next();

			List<RouteItem> routes = nlink.getRouteItems(); // 获取链路的路由项
			routeTabel0x.addAll(routes); // 添加到路由表

			nlink.setSRv6Router(this);
			nlink.addIPv6LinkStateListener(listener); // 添加链路状态监听器
			nlink.setReceiveConsumer(srhReceive); // 设置接收处理器
			if (nlink instanceof ControlledIPv6NetworkLink) {
				((ControlledIPv6NetworkLink) nlink).setRerouteConsumer(defaultReroute); // 设置重路由处理器
				((ControlledIPv6NetworkLink) nlink).setCongressCondition(congressLock, congressCondition); // 设置拥塞条件
			}
		}

		// 预处理和排序路由项
		for (Iterator<RouteItem> iterator = routeTabel0x.iterator(); iterator.hasNext();) {
			RouteItem routeItem = (RouteItem) iterator.next();
			routeItem.updateCost(); // 预排序
		}
		Collections.sort(routeTabel0x); // 排序路由表

		// 构建前缀长度索引的路由表
		ArrayList<Map<IPv6Address, List<RouteItem>>> routeTabel1x = new ArrayList<Map<IPv6Address, List<RouteItem>>>(
				IPv6_BITS + 1);
		for (int i = 0; i < IPv6_BITS + 1; i++) {
			routeTabel1x.add(new HashMap<IPv6Address, List<RouteItem>>(1024, 0.5f));
		}

		// 按前缀长度组织路由表
		for (RouteItem item : routeTabel0x) {
			IPv6AddressGroup iag = item.getDestination();
			Map<IPv6Address, List<RouteItem>> map = routeTabel1x.get(iag.getPrefixLength());
			List<RouteItem> newlist = new ArrayList<RouteItem>();
			List<RouteItem> oldlist = map.putIfAbsent(iag.getAddress(), newlist);
			if (oldlist == null) {
				oldlist = newlist;
			}
			oldlist.add(item);
		}
		// System.out.println(routeTabel1x);
		routeTable0 = routeTabel0x; // 更新平面路由表
		routeTabel1 = routeTabel1x; // 更新索引路由表
	}

	private IPv6AddressGroup locator; // SRv6定位器
	private long asn = new SecureRandom().nextLong(1, Long.MAX_VALUE); // 自治系统号
	private volatile String deviceName; // 设备名称（随路由信息广播）

	public String getDeviceName() {
		return deviceName;
	}

	public void setDeviceName(String deviceName) {
		this.deviceName = deviceName;
	}

	public IPv6AddressGroup getLocator() {
		return locator;
	}

	public long getASN() {
		return asn;
	}

	public void setASN(long asn) {
		this.asn = asn;
	}

	// 设置定位器并更新路由表
	public void setLocator(IPv6AddressGroup locator) {
		this.locator = locator;
		updateRouteTabel();
	}

	// 插入SRH并路由数据包
	public void insertSRHandRoutePacket(IPv6NetworkLink link, IPv6Packet ipp) {
		insertHopByHopHeader(ipp);
		insertSRHeader(ipp); // 插入段路由头
		routePacket(link, ipp); // 路由数据包
	}


	private static final PadNHopByHopTLV pad4 = new PadNHopByHopTLV(4);

	// 插入逐跳路由头
	public boolean insertHopByHopHeader(IPv6Packet ipp) {
		if (ipp.getHopByHopHeader() != null) {
			return false;
		}
		IPv6HopByHopHeader hbh = new IPv6HopByHopHeader();
		hbh.getTlvs().add(pad4);
		UUID pid = KLALBUtils.createGlobalUUID();
		hbh.getTlvs().add(new KLALBOAMHopByHopTLV(0, ipp.getHopLimit(), true, false, true, pid,
				clock.getCurrentTimeNTP64().longValue()));
		ipp.getHeaders().add(0, hbh); // 添加Hop头
		ipp.setHopByHopHeader(hbh);
		return true;
	}

	// 插入段路由头
	public boolean insertSRHeader(IPv6Packet ipp) {
		// 如果已有SRH，返回false
		if (ipp.getSegmentRoutingHeader() != null) {
			return false;
		}
		// 如果KLALB路由协议可用，创建段列表
		if (klalbRouteProtol != null) {
			IPv6SegmentRoutingHeader segs = klalbRouteProtol.createSegmentList(ipp.getDestinationAddress());
			// System.out.println(segs);
			if (segs != null && (!segs.getAddresses().isEmpty())) {

				// 创建SRH头

				ipp.getHeaders().add(segs); // 添加SRH头
				ipp.setRoutingHeader(segs);
				ipp.setDestinationAddress(segs.getAddresses().get(segs.getAddresses().size() - 1)); // 更新目的地址为最后一个段

				return true;
			}
		}
		return false;
	}

	private volatile List<RouteItem> routeTable0 = new ArrayList<>(); // 当前路由表

	// 前缀长度索引的路由表
	private volatile List<Map<IPv6Address, List<RouteItem>>> routeTabel1 = new ArrayList<Map<IPv6Address, List<RouteItem>>>(
			IPv6_BITS + 1);
	{
		// 初始化索引路由表
		for (int i = 0; i < IPv6_BITS + 1; i++) {
			routeTabel1.add(new HashMap<IPv6Address, List<RouteItem>>(1024, 0.5f));
		}
	}

	private void routePacket(IPv6Packet iPv6Packet) {
		routePacket(null, iPv6Packet, false);
	}

	// 路由数据包（默认非重路由）
	private void routePacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet) {
		routePacket(linkfrom, iPv6Packet, false);
	}

	// 路由数据包主方法
	private void routePacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute) {
		StringBuilder dbg = null;
		if (debug) {
			dbg = new StringBuilder(); // 调试信息
		}
		try {
			int hop = iPv6Packet.getHopLimit(); // 获取跳数限制
			if (hop > 0) { // 检查TTL值，只有大于0才会被转发
				// 搜索匹配的路由表项
				IPv6Address dest=iPv6Packet.getDestinationAddress();
				List<RouteItem> searchResult = getTabelByAddress(dest);
				if (searchResult!=null&&(!searchResult.isEmpty())) {
					// 匹配到路由表，执行负载均衡路由
					routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult);
					return;
				}

				if (debug)
					dbg.append("noroute\n");

				// 未找到路由，尝试FRR（快速重路由）保护
				IPv6SegmentRoutingHeader srh = iPv6Packet.getSegmentRoutingHeader();
				if (srh != null) {
					System.out.println("原SRH：" + srh);
					int segmentsLeft = srh.getSegmentsLeft();
					if (segmentsLeft > 0) {
						srh.getAddresses().remove(segmentsLeft); // 移除当前故障段
						segmentsLeft--;
					}
					// 创建修复段列表
					IPv6SegmentRoutingHeader repairSegments = klalbRouteProtol
							.createSegmentList(srh.getAddresses().get(segmentsLeft));
					if (repairSegments == null ||repairSegments.getAddresses().isEmpty()) {
						System.out.println("FRR保护失败");
						return;
					}
					repairSegments.getAddresses().remove(0); // 移除第一个段（当前节点）
					srh.getAddresses().addAll(segmentsLeft + 1, repairSegments.getAddresses()); // 添加修复段
					segmentsLeft += repairSegments.getAddresses().size(); // 更新剩余段数
					srh.setSegmentsLeft(segmentsLeft);
					iPv6Packet.setDestinationAddress(srh.getAddresses().get(segmentsLeft)); // 更新目的地址
				} else {
					return;
				}
				System.out.println("FRR修复SRH：" + srh);
				// 重新搜索路由表
				List<RouteItem> searchResult2 = getTabelByAddress(dest);
				if (searchResult2!=null&&(!searchResult2.isEmpty())) {
					routingLoadBalance(linkfrom, iPv6Packet, reroute, dbg, searchResult2);
					return;
				}

			} else {
				// TTL超时，发送ICMP超时消息
				sendTTLExceedPacket(iPv6Packet);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (debug) {
				System.out.println(dbg.toString()); // 输出调试信息
			}
		}
	}

	// 搜索路由表找到匹配的路由项
	/*private List<RouteItem> searchTable(IPv6Packet iPv6Packet, StringBuilder dbg)
			throws IllegalRawDataException, IOException {
		if (debug) {
			dbg.append("----------------------------------------\n");
			dbg.append("packet:" + iPv6Packet.getSourceAddress() + " -> " + iPv6Packet.getDestinationAddress() + "\n");
		}

		IPv6Address rk6 = iPv6Packet.getDestinationAddress();
		List<RouteItem> table = getTabelByAddress(rk6);

		RouteItem prevr = null;
		List<RouteItem> routes = new ArrayList<>();

		if (table == null) {
			return routes; // 无匹配路由
		}

		// 遍历路由表，筛选可用路由
		for (RouteItem tri : table) {
			
			// 检查ECMP（等价多路径）条件
			if (prevr != null) {
				if (!tri.ECMPequals(prevr)) {
					return routes; // 非ECMP路由，返回当前结果
				}
			}
			routes.add(tri); // 添加到可用路由列表
			prevr = tri;
		}
		return routes;
	}*/

	private List<RouteItem> getTabelByAddress(IPv6Address rk6) {
		List<RouteItem> table = null;
		// 最长前缀匹配搜索
		for (int i = 128; i >= 0; i--) {
			rk6 = rk6.maskWith(IPv6Address.createMask(i)); // 应用掩码
			table = routeTabel1.get(i).get(rk6); // 查找匹配的路由表
			if (table != null) {
				break; // 找到匹配
			}
		}
		return table;
	}

	private ReentrantLock congressLock = new ReentrantLock(); // 拥塞锁
	private Condition congressCondition = congressLock.newCondition(); // 拥塞条件

	// 负载均衡路由
	private boolean routingLoadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute,
			StringBuilder dbg, List<RouteItem> routes) throws IllegalRawDataException, IOException {

		if(routes==null||routes.isEmpty()) {
			//System.out.println("Route not found:" + iPv6Packet);
			return false;
		}
	
		for (double i = 1; i < 100; i += 0.1) {
			if (loadBalance(linkfrom, iPv6Packet, reroute, dbg, routes,   i)) {
				return true;
			}

				iPv6Packet.markCE(); // 标记拥塞
				if (debug) {
					dbg.append("ECN enabled.\n");
				}
			
		}
		//System.out.println("Send failed:" + iPv6Packet);
		LosscountAdder.inc(1);
		
		if (debug) {
			dbg.append("miss.\n"); // 路由失败
		}
		return false; // 路由失败
	}

	private boolean loadBalance(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, boolean reroute, StringBuilder dbg,
			List<RouteItem> routes, double cscale)
			throws IllegalRawDataException, IOException {
		// 遍历可用路由进行负载均衡
		for (RouteItem tri : routes) {
			IPv6NetworkLink link = tri.getDestlink();
			if (!link.isUp()) { // 检查链路状态
				if (debug) {
					dbg.append(tri + "\n");
					dbg.append("linkdown.\n");
				}
				continue; // 跳过断开链路
			}
			if (link instanceof ControlledIPv6NetworkLink) {
				if (((ControlledIPv6NetworkLink) link).isCongestion(iPv6Packet, cscale)) { // 检查拥塞
					if (debug) {
						dbg.append(tri + "\n");
						dbg.append("congress.\n");
					}
					continue; // 跳过拥塞链路
				}

			}
			if (debug) {
				dbg.append(tri + "\n");
				dbg.append("matched.\n");
			}
			// 找到可用链路，处理数据包
			processPacket(linkfrom, iPv6Packet, tri, reroute);
			return true;
		}
		return false;
	}

	// 处理数据包转发
	private void processPacket(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, RouteItem ri, boolean reroute)
			throws IllegalRawDataException, IOException {
		int hop = iPv6Packet.getHopLimit();

		if (ri.getDestlink().isLoopBack()) { // 环回链路处理
			IPv6SegmentRoutingHeader srhh = iPv6Packet.getSegmentRoutingHeader();
			if (srhh != null) {
				processSRv6Packet(linkfrom, iPv6Packet, ri, srhh, iPv6Packet.getHopByHopHeader(), reroute); // SRv6特殊处理
			} else {
				sendPacketToRouteItem(iPv6Packet, ri);
			}
		} else { // 普通链路处理
			// 检查重路由计数
			if (iPv6Packet.getRerouteCounter().getAndIncrement() >= MAX_REROUTE_COUNT) {
				return; // 超过最大重路由次数，丢弃
			}

			if (!reroute) {
				hop--; // 减少TTL（非重路由时）
			}

			if (hop > 0) { // TTL有效
				iPv6Packet.setHopLimit(hop); // 更新TTL
				sendPacketToRouteItem(iPv6Packet, ri); // 发送数据包
			} else {
				sendTTLExceedPacket(iPv6Packet); // TTL超时
			}
		}
	}

	private void sendPacketToRouteItem(IPv6Packet iPv6Packet, RouteItem ri) throws IOException {
		if (iPv6Packet.getPayload() instanceof ICMPv6PostcardPacket && ri.getDestlink().isLoopBack()) {
			onPostcardReceive(iPv6Packet);
		} else {
			ri.getDestlink().sendPacket(iPv6Packet, ri.getNexthop());
		}
	}

	private void onPostcardReceive(IPv6Packet postcards) {
		ICMPv6PostcardPacket postcardsi = (ICMPv6PostcardPacket) postcards.getPayload();
		for (PostcardEntry postcard : postcardsi.getPostcards()) {
			IPv6Address sid = postcard.getSID();

			List<RouteItem> ris = getTabelByAddress(sid);
			if (ris != null) {
				for (RouteItem ri : ris) {
					if (ri.getNexthop().equals(sid)) {
						if (ri.getDestlink() instanceof KLALBRemoteLink) {
							KLALBRemoteLink rem = (KLALBRemoteLink) ri.getDestlink();
							rem.onPostcardReceive(postcard);
						}
					}
				}
			}
		}

	}

	// 发送ICMP TTL超时消息
	private void sendTTLExceedPacket(IPv6Packet iPv6Packet) throws IOException, IllegalRawDataException {
		enqueuePacketSendTask(() -> {
			// 构建IPv6数据包封装ICMP消息
			IPv6Packet icmpv = new IPv6Packet();
			icmpv.setSourceAddress(locator.getAddress());
			icmpv.setDestinationAddress(iPv6Packet.getSourceAddress());
			icmpv.setTrafficClass(iPv6Packet.getTrafficClass());
			icmpv.setVersion(6);
			icmpv.setFlowLabel(0);
			icmpv.setHopLimit(255); // ICMP消息TTL设为最大值
			ICMPv6TimeExceededPacket ipl = ICMPv6TimeExceededPacket.createHopLimitExceeded(iPv6Packet);
			ipl.setParent(icmpv);
			ipl.updateChecksum();
			icmpv.setPayload(ipl);
			return icmpv;
		});

	}

	// 处理SRv6数据包
	private void processSRv6Packet(IPv6NetworkLink linkfrom, IPv6Packet iPv6Packet, RouteItem ri,
			IPv6SegmentRoutingHeader srhh, IPv6HopByHopHeader iPv6HopByHopHeader, boolean reroute)
			throws IllegalRawDataException, IOException {

		if (srhh.getSegmentsLeft() <= 0) { // 所有段已处理完毕
			if (iPv6HopByHopHeader != null) {
				int sl = srhh.getSegmentsLeft();
				// IPv6Address prevSID
				// =sl+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(sl+1);
				if (linkfrom instanceof KLALBRemoteLink) {
					processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
							((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
				}
			}
			// System.out.println(iPv6HopByHopHeader);
			sendPacketToRouteItem(iPv6Packet, ri);
		} else {
			if (reroute) {
				// 重路由处理
			} else {
				int oldSL = srhh.getSegmentsLeft();
				if (iPv6HopByHopHeader != null) {
					// IPv6Address prevSID
					// =oldSL+1>=srhh.getAddresses().size()?iPv6Packet.getSourceAddress():srhh.getAddresses().get(oldSL+1);
					if (linkfrom instanceof KLALBRemoteLink) {
						processKLALBOAM(iPv6Packet, linkfrom.getAddressGroups().get(0).getAddress(),
								((KLALBRemoteLink) linkfrom).getRemoteVaddr().getAddress(), iPv6HopByHopHeader);
					}
				}
				// 正常SRv6处理：移动到下一个段
				int newSL = oldSL - 1;
				srhh.setSegmentsLeft(newSL); // 更新剩余段数
				iPv6Packet.setDestinationAddress(srhh.getAddresses().get(newSL)); // 更新目的地址
			}
			// 记录热点地址（用于流量工程）
			if (iPv6Packet.getPayload().getProtocolNumber() != KLALBRoutingProtocol.DEFAULT_PROTOCOL_NUMBER)
				klalbRouteProtol.putHotspotAddress(iPv6Packet.getSourceAddress());
			routePacket(linkfrom, iPv6Packet, reroute); // 继续路由
		}
	}

	private void processKLALBOAM(IPv6Packet iPv6Packet, IPv6Address sourceSID, IPv6Address prevSID,
			IPv6HopByHopHeader iPv6HopByHopHeader) {
		KLALBOAMHopByHopTLV oam = null;
		List<IPv6HopByHopTLV> tlvs = iPv6HopByHopHeader.getTlvs();
		KLALBPassportHopByHopTLV prevEndPassport = null;
		for (IPv6HopByHopTLV tlv : tlvs) {
			if (tlv instanceof KLALBOAMHopByHopTLV) {
				oam = (KLALBOAMHopByHopTLV) tlv;
			} else if (tlv instanceof KLALBPassportHopByHopTLV) {
				prevEndPassport = (KLALBPassportHopByHopTLV) tlv;
			}
		}
		if (oam != null) {
			long timentp = clock.getCurrentTimeNTP64().longValue();
			int packetLength = (int) iPv6Packet.getTotalLength();
			long oamt = oam.getTimestamp();
			long delta = timentp - oamt;
			long prevhop = oamt;
			if (prevEndPassport != null) {
				prevhop += prevEndPassport.getTimestampOffsetLong();
			}

			if (oam.isRecordPassport()) {
				tlvs.add(new KLALBPassportHopByHopTLV(packetLength, (int) (delta >> 4)));
			}
			if (iPv6Packet.getPayload() instanceof ICMPv6PostcardPacket) {
			} else {
				boolean phop = oam.isPostcardToPreviousHop();
				boolean psrc = oam.isPostcardToSource();
				// System.out.println(iPv6Packet.getPayload());
				if (phop) {
					putPostcard(locator.getAddress(), prevSID, sourceSID, oam.getUUID(), prevhop, timentp - prevhop,
							packetLength);
				}
				if (psrc) {
					putPostcard(locator.getAddress(), iPv6Packet.getSourceAddress(), sourceSID, oam.getUUID(), oamt,
							delta, packetLength);
				}
			}
		}
	}

	private TimeoutConcurrentHashMap<Pair<IPv6Address, IPv6Address>, MessageBatcher<PostcardEntry>> postcardBatch = new TimeoutConcurrentHashMap<>(
			1000000000L);

	private void putPostcard(IPv6Address src, IPv6Address dst, IPv6Address srcSID, UUID uuid, long timeStamp,
			long delta, int packetLength) {
		
		PostcardEntry pn = new PostcardEntry(srcSID, uuid, timeStamp, (int) (delta >> 4), packetLength);
		/*Pair<IPv6Address, IPv6Address> addressPair = new Pair<IPv6Address, IPv6Address>(src, dst);
		MessageBatcher<PostcardEntry> batch = postcardBatch.computeIfAbsent(addressPair, (k) -> {
			MessageBatcher<PostcardEntry> mb = new ArrayListMessageBatcher<PostcardEntry>(30, 2000000L);
			mb.setConsumer((list) -> {
				enqueuePacketSendTask(() -> {
					IPv6Packet icmpv = new IPv6Packet();
					icmpv.setSourceAddress(k.first);
					icmpv.setDestinationAddress(k.second);
					icmpv.setTrafficClass(0);
					icmpv.setVersion(6);
					icmpv.setFlowLabel(0);
					icmpv.setHopLimit(255); // ICMP消息TTL设为最大值
					ICMPv6PostcardPacket ipl = new ICMPv6PostcardPacket();
					ipl.getPostcards().addAll(list);
					ipl.setParent(icmpv);
					ipl.updateChecksum();
					icmpv.setPayload(ipl);
					return icmpv;
				});
			});
			return mb;
		});
		postcardBatch.refresh(addressPair);
		batch.putMessage(pn);*/
		enqueuePacketSendTask(() -> {
			IPv6Packet icmpv = new IPv6Packet();
			icmpv.setSourceAddress(src);
			icmpv.setDestinationAddress(dst);
			icmpv.setTrafficClass(0);
			icmpv.setVersion(6);
			icmpv.setFlowLabel(0);
			icmpv.setHopLimit(255); // ICMP消息TTL设为最大值
			ICMPv6PostcardPacket ipl = new ICMPv6PostcardPacket();
			ipl.getPostcards().addAll(List.of(pn));
			ipl.setParent(icmpv);
			ipl.updateChecksum();
			icmpv.setPayload(ipl);
			return icmpv;
		});
	}

	private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2(
			(int) (Runtime.getRuntime().availableProcessors()), Thread.ofVirtual().name("SRv6 Routing").factory());
	
	//private static HighPerformanceExecutor2 defaultExecutor = new HighPerformanceExecutor2(4, Thread.ofVirtual().name("SRv6 Routing").factory());

	/*public static HighPerformanceExecutor2 getDefaultExecutor() {
		return defaultExecutor;
	}*/

	// private ArrayBlockingQueue<Supplier<IPv6Packet>> packetQueue=new
	// ArrayBlockingQueue<>(10000);
	public void enqueuePacketSendTask(Supplier<IPv6Packet> sendTask) {
		// packetQueue.add(object);
		switch(performanceStrategy) {
			case SINGLE_CORE:
				runPacketSendTask0(sendTask, false);
			break;
			case MULTI_FILL:
			case MULTI_SCATTER:
				defaultExecutor.executeWithCongestionReport((state) -> {
					runPacketSendTask0(sendTask, state);
				}, 20,performanceStrategy);

				break;
		}
	}
	public void runPacketSendTask0(Supplier<IPv6Packet> sendTask,boolean ecn) {
		try {
			long start=System.nanoTime();
			IPv6Packet packet=sendTask.get();
			if(ecn) {
				packet.markCE();
			}
			insertSRHandRoutePacket(null, packet); // 插入SRH并路由
			long time=System.nanoTime()-start;
			backplaneCount(time,ecn);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void runPacketSendTask(Supplier<IPv6Packet> sendTask) {
		runPacketSendTask0(sendTask,false);
	}

	public void onReceive(IPv6NetworkLink link,IPv6Packet t){
		if (unduplicate(t)) {
			insertSRHandRoutePacket(link, t); // 插入SRH并路由数据包
		}
	}
	
	public void enqueuePacketReceiveTask(IPv6NetworkLink link, Supplier<IPv6Packet> pack) {
		defaultExecutor.executeWithCongestionReport((state) -> {
			try {
				long start=System.nanoTime();
				IPv6Packet packet = pack.get();
				if(state) {
						packet.markCE();
					}
				onReceive(link ,packet);
				long time=System.nanoTime()-start;
				backplaneCount(time,state);
			} catch (Exception e) {
				e.printStackTrace();
			}
		},20,performanceStrategy);
	}

	public void enqueuePacket(IPv6Packet packet) {
		enqueuePacketSendTask(() -> {
			return packet;
		});
	}
	
	//private BandwidthSampler sampler=new BandwidthSampler();
	private FixedSizeStripedLongCounter timeAdder=KLALBUtils.createCounter();
	private FixedSizeStripedLongCounter countAdder=KLALBUtils.createCounter();
	private FixedSizeStripedLongCounter ECNcountAdder=KLALBUtils.createCounter();
	private FixedSizeStripedLongCounter LosscountAdder=KLALBUtils.createCounter();
	private void backplaneCount(long time,boolean ECN) {
		timeAdder.inc(time);
		countAdder.inc(1);
		if(ECN) {
			ECNcountAdder.inc(1);
		}
	}
	private volatile long backplaneTime=0;
	private volatile double ECNRate=0;
	private volatile double LossRate=0;
	private volatile long backplanePPS=0;
	private volatile long backplanePPSMax=0;
	private volatile long prevTime=System.nanoTime();
	
	private Timer backplaneTimer=new Timer();
	private void updateBackplaneCounter() {
		long curr=System.nanoTime();
		long totalTime=timeAdder.getAndReset();
		long totalCount=countAdder.getAndReset();
		long ECNCount=ECNcountAdder.getAndReset();
		long LossCount=LosscountAdder.getAndReset();
		if(totalCount!=0) {
		backplaneTime=totalTime/totalCount;
		ECNRate=((double)ECNCount)/totalCount;
		LossRate=((double)LossCount)/totalCount;
		}
		backplanePPS=totalCount*1000000000L/(curr-prevTime);
		if(backplanePPSMax<backplanePPS) {
			backplanePPSMax=backplanePPS;
		}else {
			backplanePPSMax=(backplanePPSMax*999+backplanePPS)/1000;
		}
		prevTime=curr;
	}

	
	public long getBackplaneTime() {
		return backplaneTime;
	}

	public long getBackplanePPS() {
		return backplanePPS;
	}

	public long getBackplanePPSMax() {
		return backplanePPSMax;
	}
	
	public double getECNRate() {
		return ECNRate;
	}

	public double getLossRate() {
		return LossRate;
	}

	// 构造函数
	public SRv6Router(IPv6AddressGroup hostAddress, HighAccuracyClock clock) {
		super();
		this.locator = hostAddress;
		this.clock = clock;
		// initWorkerThreads();
		// 创建环回链路
		this.inLoopBack = new LoopbackIPv6NetworkLink(
				List.of(new IPv6AddressGroup(IPv6Address.LOOPBACK, 128), hostAddress), this);
		linkTabel.add(inLoopBack); // 添加到链路表
		backplaneTimer.scheduleAtFixedRate(new TimerTask() {
			
			@Override
			public void run() {
		    	   updateBackplaneCounter();
			}
		}, 100, 100);
	}

	/*
	 * private void initWorkerThreads() { int
	 * threads=Runtime.getRuntime().availableProcessors()*4; for(int
	 * i=0;i<threads;i++) { ThreadTool.makeVThread("SRv6 Router Thread"+i,()->{
	 * while(true) { try { Supplier<IPv6Packet>packetSup= packetQueue.take();
	 * insertSRHandRoutePacket(packetSup.get()); // 插入SRH并路由 }catch(Exception e) {
	 * e.printStackTrace(); } } } ).start(); } }
	 */

	private KLALBRoutingProtocol klalbRouteProtol = null; // KLALB路由协议实例

	// 启动KLALB路由协议
	public void runKLALBRouteProtocol() {
		if (klalbRouteProtol != null)
			throw new IllegalStateException("KLALB routing protocol is already running!");
		klalbRouteProtol = new KLALBRoutingProtocol(this);
		klalbRouteProtol.start(); // 启动协议
	}

	public KLALBRoutingProtocol getKlalbRouteProtol() {
		return klalbRouteProtol;
	}

	public LoopbackIPv6NetworkLink getinLoopback() {
		return inLoopBack;
	}

	// 获取邻居信息
	public List<Neighbor> getNeighbors() {
		List<Neighbor> result = new ArrayList<>();
		List<IPv6NetworkLink> links = getLinkTabel();
		Object[] nls = links.toArray();
		for (int i = 0; i < nls.length; i++) {
			IPv6NetworkLink nl = (IPv6NetworkLink) nls[i];
			if ((!nl.isLoopBack())&&nl.isUp()) { // 排除环回接口
				List<Neighbor> neis = nl.getNeighborsInfo();
				for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
					Neighbor addresses = (Neighbor) iteratorx.next();
					result.add(addresses); // 添加邻居信息
				}
			}
		}
		return result;
	}

	// 获取所有SID
	public Set<IPv6AddressGroup> getLocators() {
		Set<IPv6AddressGroup> result = new HashSet<>();
		List<IPv6NetworkLink> links = getLinkTabel();
		Object[] nls = links.toArray();
		for (int i = 0; i < nls.length; i++) {
			IPv6NetworkLink nl = (IPv6NetworkLink) nls[i];
			if (!nl.isLoopBack()) { // 排除环回接口
				List<Neighbor> neis = nl.getNeighborsInfo();
				for (Iterator<Neighbor> iteratorx = neis.iterator(); iteratorx.hasNext();) {
					Neighbor addresses = (Neighbor) iteratorx.next();
					if (addresses.getLocator() != null)
						result.add(addresses.getLocator()); // 添加邻居SID
				}
			}
		}
		return result;
	}



	
}