package org.kne.cloud.network.ipv6;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.UUID;

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

public class PostcardEntry extends NetworkPacket {
    public static final int POSTCARD_ENTRY_SIZE = 48;
    private ByteBuffer data = NetworkPacket.bufferAllocator.allocate(POSTCARD_ENTRY_SIZE);
    
    // 字段偏移量常量
    private static final int SID_OFFSET = 0;           // 16字节
    private static final int UUID_OFFSET = 16;           // 16字节
    private static final int SEQUENCE_OFFSET = 16+16;      // 8字节
    private static final int TIMESTAMP_BASE_OFFSET = 16+16;     // 8字节
    private static final int TIMESTAMP_DELTA_OFFSET = 24+16;   // 4字节
    private static final int PACKET_SIZE_OFFSET = 28+16;   // 2字节
    private static final int RESERVED_OFFSET = 30+16;      // 6字节

    public PostcardEntry(IPv6Address sid,UUID uuid,long timestampBase,int timestampDelta,int packetSize) {
    	setSID(sid);
    	setPacketUUID(uuid);
    	setTimestampBase(timestampBase);
    	setTimestampDelta(timestampDelta);
    	setPacketSize(packetSize);
        data.limit(POSTCARD_ENTRY_SIZE);
    	
    }
    
   

	
    
	 public void setSID(IPv6Address sid) {
			data.putLong(SID_OFFSET, sid.getHigh());
			data.putLong(SID_OFFSET+8, sid.getLow());
		}
	 
	 public IPv6Address getSID() {
		 long high=data.getLong(SID_OFFSET);
		 long low =data.getLong(SID_OFFSET+8);
		 return new IPv6Address(high, low);
	 }
	
    public PostcardEntry() {
        // 初始化缓冲区
        data.limit(POSTCARD_ENTRY_SIZE);
    }

    @Override
    public long getTotalLength() {
        return POSTCARD_ENTRY_SIZE;
    }

    @Override
    public void writeToChannel(WritableByteChannel dto) throws IOException {
        data.position(0);
        data.limit(POSTCARD_ENTRY_SIZE);
        dto.write(data.slice());
    }

    @Override
    public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
        data.clear();
        data.limit(POSTCARD_ENTRY_SIZE);
        KNEChannels.readFully(din, data);
        data.flip();
    }

    @Override
    protected boolean needEndPosition() {
        return false;
    }

    /**
     * 设置包UUID（16字节）
     */
    public void setPacketUUID(UUID uuid) {
        data.putLong(UUID_OFFSET, uuid.getMostSignificantBits());
        data.putLong(UUID_OFFSET + 8, uuid.getLeastSignificantBits());
    }

    /**
     * 获取包UUID（16字节）
     */
    public UUID getPacketUUID() {
        long mostSigBits = data.getLong(UUID_OFFSET);
        long leastSigBits = data.getLong(UUID_OFFSET + 8);
        return new UUID(mostSigBits, leastSigBits);
    }

    /**
     * 设置序列号（8字节）
     */
    public void setSequence(long sequence) {
        data.putLong(SEQUENCE_OFFSET, sequence);
    }

    /**
     * 获取序列号（8字节）
     */
    public long getSequence() {
        return data.getLong(SEQUENCE_OFFSET);
    }

    /**
     * 设置时间戳（8字节）
     */
    public void setTimestampBase(long timestamp) {
        data.putLong(TIMESTAMP_BASE_OFFSET, timestamp);
    }

    /**
     * 获取时间戳（8字节）
     */
    public long getTimestampBase() {
        return data.getLong(TIMESTAMP_BASE_OFFSET);
    }
    
    public int getTimestampDelta() {
    	return data.getInt(TIMESTAMP_DELTA_OFFSET);
    }
    
    public void setTimestampDelta(int delta) {
    	data.putInt(TIMESTAMP_DELTA_OFFSET, delta);
    }
    
    /**
     * 设置包大小（2字节，无符号）
     */
    public void setPacketSize(int packetSize) {
        if (packetSize < 0 || packetSize > 65535) {
            throw new IllegalArgumentException("Packet size must be between 0 and 65535");
        }
        data.putShort(PACKET_SIZE_OFFSET, (short) packetSize);
    }

    /**
     * 获取包大小（2字节，无符号）
     */
    public int getPacketSize() {
        return data.getShort(PACKET_SIZE_OFFSET) & 0xFFFF;
    }

    /**
     * 设置保留字段（2字节）
     */
    public void setReserved(int reserved) {
            data.putChar(RESERVED_OFFSET ,(char) reserved);
    }

    /**
     * 获取保留字段（2字节）
     */
    public int getReserved() {
        return data.getChar(RESERVED_OFFSET);
    }

    /**
     * 清空保留字段（设置为0）
     */
    public void clearReserved() {
       setReserved(0);
    }

    

    

  

    @Override
    public String toString() {
        UUID uuid = getPacketUUID();
        return String.format("PostcardEntry[uuid=%s, seq=%d, time=%d, delta=%d, size=%d]",
                uuid.toString(), 
                getSequence(),
                getTimestampBase(),
                getTimestampDelta(),
                getPacketSize());
    }

	public double getTimestampDeltaLong() {
		return ((long)getTimestampDelta())<<4;
	}

    
}