package org.kne.cloud.network.ipv6;

import java.io.IOException;
import java.nio.ByteBuffer;

import org.kne.cloud.network.NetworkPacket;
import org.kne.io.KNEChannels;

public class ICMPv6TimeExceededPacket extends ICMPv6Packet {
    
    // 代码值常量
    public static final int CODE_HOP_LIMIT_EXCEEDED = 0;      // 跳数限制超时
    public static final int CODE_FRAGMENT_REASSEMBLY_EXCEEDED = 1; // 分片重组超时
    
    public ICMPv6TimeExceededPacket(int code) {
        super(TYPE_TIME_EXCEEDED, code);
        setUnused(0);
    }
    
    public ICMPv6TimeExceededPacket(ByteBuffer bb) {
		super(bb, true);
	}

	/**
     * 获取未使用字段（通常为0）
     */
    public int getUnused() {
        return getHeader().getInt(4);
    }
    
    /**
     * 设置未使用字段（通常设为0）
     */
    public void setUnused(int unused) {
    	getHeader().putInt(4, unused);
    }
    
    
    /**
     * 创建跳数限制超时包
     */
    public static ICMPv6TimeExceededPacket createHopLimitExceeded(IPv6Packet originalPacket) {
        ICMPv6TimeExceededPacket packet = new ICMPv6TimeExceededPacket(CODE_HOP_LIMIT_EXCEEDED);
        
        // 包含原始数据包的前缀（根据RFC，尽可能包含但不超出最小MTU）
        if (originalPacket == null) {
        	throw new NullPointerException("originalPacket is null!");
        }
            // 这里简化处理，实际应该序列化原始包的前1280字节（IPv6最小MTU）
            ByteBuffer buffer = NetworkPacket.bufferAllocator.allocate(65536);
            buffer.clear();
            try {
				originalPacket.writeToChannel(KNEChannels.newWritableChannel(buffer));
			} catch (IOException e) {
				e.printStackTrace();
			}
            buffer.flip();
            buffer.limit(Math.min(1280, buffer.limit()));
            packet.getData().clear();
            packet.getData().put(buffer);
            packet.getData().flip();
        return packet;
    }
    
    @Override
    public String toString() {
        String codeStr = getCode() == CODE_HOP_LIMIT_EXCEEDED ? 
                        "Hop Limit Exceeded" : "Fragment Reassembly Time Exceeded";
        return String.format("ICMPv6 Time Exceeded [%s, OriginalPrefix:%d bytes]", 
                           codeStr, getDataLength());
    }
}