package org.kne.cloud.network.tun;

import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Windows IP地址管理类 提供对MIB_UNICASTIPADDRESS_ROW和MIB_UNICASTIPADDRESS_TABLE的Java封装
 */
public class WindowsIPAddressManager {

	// 内存布局定义
	public static final AddressLayout POINTER = ValueLayout.ADDRESS;
	public static final ValueLayout.OfInt DWORD = ValueLayout.JAVA_INT;
	public static final ValueLayout.OfLong DWORD64 = ValueLayout.JAVA_LONG;
	public static final ValueLayout.OfByte BYTE = ValueLayout.JAVA_BYTE;
	public static final ValueLayout.OfShort WORD = ValueLayout.JAVA_SHORT;
	public static final ValueLayout.OfBoolean BOOLEAN_LAYOUT = ValueLayout.JAVA_BOOLEAN;

	// 常量定义
	public static final int NO_ERROR = 0;
	public static final int ERROR_NOT_FOUND = 1168;
	public static final int ERROR_OBJECT_ALREADY_EXISTS = 5010;
	public static final int NET_IFINDEX_UNSPECIFIED = 0;
	public static final long NET_IFLUID_UNSPECIFIED = 0;

	// SCOPE_ID 结构 (ULONG)
	public static final GroupLayout SCOPE_ID_LAYOUT = MemoryLayout.structLayout(DWORD.withName("Value"));

	// LARGE_INTEGER 结构 (64位有符号整数)
	public static final GroupLayout LARGE_INTEGER_LAYOUT = MemoryLayout.structLayout(DWORD64.withName("QuadPart"));

	// SOCKADDR_IN (IPv4地址)
	public static final GroupLayout SOCKADDR_IN_LAYOUT = MemoryLayout.structLayout(WORD.withName("sin_family"), // ADDRESS_FAMILY
																												// (AF_INET
																												// = 2)
			WORD.withName("sin_port"), // USHORT
			MemoryLayout.sequenceLayout(4, BYTE).withName("sin_addr"), // IN_ADDR (4 bytes)
			MemoryLayout.sequenceLayout(8, BYTE).withName("sin_zero") // 填充字节
	);

	// IN6_ADDR (IPv6地址，16字节)
	public static final GroupLayout IN6_ADDR_LAYOUT = MemoryLayout
			.structLayout(MemoryLayout.sequenceLayout(16, BYTE).withName("s6_bytes"));

	// SOCKADDR_IN6 (IPv6地址结构)
	public static final GroupLayout SOCKADDR_IN6_LAYOUT = MemoryLayout.structLayout(WORD.withName("sin6_family"), // ADDRESS_FAMILY
																													// (AF_INET6
																													// =
																													// 23)
			WORD.withName("sin6_port"), // USHORT
			DWORD.withName("sin6_flowinfo"), // ULONG
			IN6_ADDR_LAYOUT.withName("sin6_addr"), DWORD.withName("sin6_scope_id") // ULONG
	);

	// SOCKADDR_INET 联合 (IPv4或IPv6地址)
	public static final GroupLayout SOCKADDR_INET_LAYOUT = MemoryLayout.structLayout(MemoryLayout
			.unionLayout(SOCKADDR_IN_LAYOUT.withName("Ipv4"), SOCKADDR_IN6_LAYOUT.withName("Ipv6")).withName("u"),
			WORD.withName("si_family") // 地址族
	);

	// NET_LUID 结构 (64位网络接口标识符)
	public static final GroupLayout NET_LUID_LAYOUT = MemoryLayout.structLayout(DWORD64.withName("Value"));

	// MIB_UNICASTIPADDRESS_ROW 结构体布局
	public static final GroupLayout MIB_UNICASTIPADDRESS_ROW_LAYOUT;

	static {
		// 动态构建结构体布局
		MemoryLayout[] layouts = {
				// 键结构
				SOCKADDR_INET_LAYOUT.withName("Address"), MemoryLayout.paddingLayout(2),
				NET_LUID_LAYOUT.withName("InterfaceLuid"), DWORD.withName("InterfaceIndex"),

				// 读写字段
				DWORD.withName("PrefixOrigin"), DWORD.withName("SuffixOrigin"), DWORD.withName("ValidLifetime"),
				DWORD.withName("PreferredLifetime"), BYTE.withName("OnLinkPrefixLength"),
				BOOLEAN_LAYOUT.withName("SkipAsSource"), MemoryLayout.paddingLayout(2),

				// 只读字段
				DWORD.withName("DadState"), SCOPE_ID_LAYOUT.withName("ScopeId"),
				LARGE_INTEGER_LAYOUT.withName("CreationTimeStamp") };

		MIB_UNICASTIPADDRESS_ROW_LAYOUT = MemoryLayout.structLayout(layouts);
	}

	// MIB_UNICASTIPADDRESS_TABLE 结构体布局
	public static final GroupLayout MIB_UNICASTIPADDRESS_TABLE_LAYOUT = MemoryLayout
			.structLayout(DWORD.withName("NumEntries"), MemoryLayout.paddingLayout(4), POINTER.withName("Table") // 指向MIB_UNICASTIPADDRESS_ROW数组的指针
			);

	// 前缀来源枚举
	public enum PrefixOrigin {
		IpPrefixOriginOther(0), IpPrefixOriginManual(1), IpPrefixOriginWellKnown(2), IpPrefixOriginDhcp(3),
		IpPrefixOriginRouterAdvertisement(4), IpPrefixOriginUnchanged(1 << 4);

		private final int value;

		PrefixOrigin(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}

		public static PrefixOrigin fromValue(int value) {
			return Arrays.stream(values()).filter(e -> e.value == value).findFirst().orElse(IpPrefixOriginOther);
		}
	}

	// 后缀来源枚举
	public enum SuffixOrigin {
		IpSuffixOriginOther(0), IpSuffixOriginManual(1), IpSuffixOriginWellKnown(2), IpSuffixOriginDhcp(3),
		IpSuffixOriginLinkLayerAddress(4), IpSuffixOriginRandom(5), IpSuffixOriginUnchanged(1 << 4);

		private final int value;

		SuffixOrigin(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}

		public static SuffixOrigin fromValue(int value) {
			return Arrays.stream(values()).filter(e -> e.value == value).findFirst().orElse(IpSuffixOriginOther);
		}
	}

	// DAD状态枚举
	public enum DadState {
		IpDadStateInvalid(0), IpDadStateTentative(1), IpDadStateDuplicate(2), IpDadStateDeprecated(3),
		IpDadStatePreferred(4);

		private final int value;

		DadState(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}

		public static DadState fromValue(int value) {
			return Arrays.stream(values()).filter(e -> e.value == value).findFirst().orElse(IpDadStateInvalid);
		}
	}

	// 地址族枚举
	public enum AddressFamily {
		AF_UNSPEC(0), AF_INET(2), AF_INET6(23);

		private final int value;

		AddressFamily(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}

		public static AddressFamily fromValue(int value) {
			return Arrays.stream(values()).filter(e -> e.value == value).findFirst().orElse(AF_UNSPEC);
		}
	}

	// Native库加载
	private static final SymbolLookup LOOKUP;
	private static final Linker LINKER = Linker.nativeLinker();

	static {
		try {
			// 加载iphlpapi.dll
			System.loadLibrary("iphlpapi");
			LOOKUP = SymbolLookup.loaderLookup();
		} catch (UnsatisfiedLinkError e) {
			throw new RuntimeException("Failed to load iphlpapi.dll", e);
		}
	}

	// Native函数句柄
	private static final MethodHandle GET_UNICAST_IP_ADDRESS_TABLE;
	private static final MethodHandle INITIALIZE_UNICAST_IP_ADDRESS_ENTRY;
	private static final MethodHandle CREATE_UNICAST_IP_ADDRESS_ENTRY;
	private static final MethodHandle DELETE_UNICAST_IP_ADDRESS_ENTRY;
	private static final MethodHandle GET_UNICAST_IP_ADDRESS_ENTRY;
	private static final MethodHandle FREE_MIB_TABLE;

	static {
		try {
			// 定义函数描述符

			// DWORD GetUnicastIpAddressTable(
			// ADDRESS_FAMILY Family,
			// PMIB_UNICASTIPADDRESS_TABLE *Table
			// );
			FunctionDescriptor getUnicastIpAddressTableDesc = FunctionDescriptor.of(DWORD, // 返回值: DWORD
					DWORD, // Family: ADDRESS_FAMILY
					POINTER // Table: PMIB_UNICASTIPADDRESS_TABLE*
			);

			// VOID InitializeUnicastIpAddressEntry(
			// PMIB_UNICASTIPADDRESS_ROW Row
			// );
			FunctionDescriptor initializeUnicastIpAddressEntryDesc = FunctionDescriptor.ofVoid(POINTER // Row:
																										// PMIB_UNICASTIPADDRESS_ROW
			);

			// DWORD CreateUnicastIpAddressEntry(
			// const MIB_UNICASTIPADDRESS_ROW *Row
			// );
			FunctionDescriptor createUnicastIpAddressEntryDesc = FunctionDescriptor.of(DWORD, // 返回值: DWORD
					POINTER // Row: const MIB_UNICASTIPADDRESS_ROW*
			);

			// DWORD DeleteUnicastIpAddressEntry(
			// const MIB_UNICASTIPADDRESS_ROW *Row
			// );
			FunctionDescriptor deleteUnicastIpAddressEntryDesc = FunctionDescriptor.of(DWORD, // 返回值: DWORD
					POINTER // Row: const MIB_UNICASTIPADDRESS_ROW*
			);

			// DWORD GetUnicastIpAddressEntry(
			// PMIB_UNICASTIPADDRESS_ROW Row
			// );
			FunctionDescriptor getUnicastIpAddressEntryDesc = FunctionDescriptor.of(DWORD, // 返回值: DWORD
					POINTER // Row: PMIB_UNICASTIPADDRESS_ROW
			);

			// VOID FreeMibTable(
			// PVOID Memory
			// );
			FunctionDescriptor freeMibTableDesc = FunctionDescriptor.ofVoid(POINTER // Memory: PVOID
			);

			// 获取函数句柄
			GET_UNICAST_IP_ADDRESS_TABLE = LINKER.downcallHandle(LOOKUP.find("GetUnicastIpAddressTable").orElseThrow(),
					getUnicastIpAddressTableDesc);

			INITIALIZE_UNICAST_IP_ADDRESS_ENTRY = LINKER.downcallHandle(
					LOOKUP.find("InitializeUnicastIpAddressEntry").orElseThrow(), initializeUnicastIpAddressEntryDesc);

			CREATE_UNICAST_IP_ADDRESS_ENTRY = LINKER.downcallHandle(
					LOOKUP.find("CreateUnicastIpAddressEntry").orElseThrow(), createUnicastIpAddressEntryDesc);

			DELETE_UNICAST_IP_ADDRESS_ENTRY = LINKER.downcallHandle(
					LOOKUP.find("DeleteUnicastIpAddressEntry").orElseThrow(), deleteUnicastIpAddressEntryDesc);

			GET_UNICAST_IP_ADDRESS_ENTRY = LINKER.downcallHandle(LOOKUP.find("GetUnicastIpAddressEntry").orElseThrow(),
					getUnicastIpAddressEntryDesc);

			FREE_MIB_TABLE = LINKER.downcallHandle(LOOKUP.find("FreeMibTable").orElseThrow(), freeMibTableDesc);

		} catch (Throwable e) {
			throw new RuntimeException("Failed to initialize Windows IP address manager", e);
		}
	}

	/**
	 * 单播IP地址行（Java表示）
	 */
	public static class UnicastIPAddressRow {
		private InetAddress address;
		private long interfaceLuid;
		private int interfaceIndex;
		private PrefixOrigin prefixOrigin;
		private SuffixOrigin suffixOrigin;
		private long validLifetime;
		private long preferredLifetime;
		private int onLinkPrefixLength;
		private boolean skipAsSource;
		private DadState dadState;
		private long scopeId;
		private Instant creationTimestamp;

		// 构造方法
		public UnicastIPAddressRow() {
		}

		public UnicastIPAddressRow(InetAddress address, long interfaceLuid) {
			this.address = address;
			this.interfaceLuid = interfaceLuid;
			this.interfaceIndex = NET_IFINDEX_UNSPECIFIED;
			this.prefixOrigin = PrefixOrigin.IpPrefixOriginManual;
			this.suffixOrigin = SuffixOrigin.IpSuffixOriginManual;
			this.validLifetime = 0xFFFFFFFFL; // 无限
			this.preferredLifetime = 0xFFFFFFFFL; // 无限
			this.onLinkPrefixLength = (address instanceof Inet4Address) ? 32 : 128;
			this.skipAsSource = false;
			this.dadState = DadState.IpDadStatePreferred;
			this.scopeId = 0;
			this.creationTimestamp = Instant.now();
		}

		// 从Native内存创建
		public static UnicastIPAddressRow fromMemorySegment(MemorySegment segment) {
			UnicastIPAddressRow row = new UnicastIPAddressRow();

			try (Arena arena = Arena.ofConfined()) {
				// 读取地址
				int family = segment.get(WORD, 0); // SOCKADDR_INET中的si_family字段
				AddressFamily addressFamily = AddressFamily.fromValue(family);

				if (addressFamily == AddressFamily.AF_INET) {
					// IPv4地址
					byte[] ipv4Bytes = new byte[4];
					for (int i = 0; i < 4; i++) {
						ipv4Bytes[i] = segment.get(BYTE, 4 + i); // sin_addr偏移
					}
					row.address = Inet4Address.getByAddress(ipv4Bytes);
					row.onLinkPrefixLength = 32;
				} else if (addressFamily == AddressFamily.AF_INET6) {
					// IPv6地址
					byte[] ipv6Bytes = new byte[16];
					MemoryLayout ipv6Layout = SOCKADDR_IN6_LAYOUT;
					long sin6AddrOffset = 8; // sin6_addr在SOCKADDR_IN6中的偏移

					for (int i = 0; i < 16; i++) {
						ipv6Bytes[i] = segment.get(BYTE, sin6AddrOffset + i);
					}
					row.address = Inet6Address.getByAddress(ipv6Bytes);
					row.onLinkPrefixLength = 128;
				}

				// 读取接口LUID
				long luidOffset = SOCKADDR_INET_LAYOUT.byteSize() + 2;
				row.interfaceLuid = segment.get(DWORD64, luidOffset);

				// 读取接口索引
				long indexOffset = luidOffset + NET_LUID_LAYOUT.byteSize();
				row.interfaceIndex = segment.get(DWORD, indexOffset);

				// 读取其他字段
				long prefixOriginOffset = indexOffset + DWORD.byteSize();
				row.prefixOrigin = PrefixOrigin.fromValue(segment.get(DWORD, prefixOriginOffset));

				long suffixOriginOffset = prefixOriginOffset + DWORD.byteSize();
				row.suffixOrigin = SuffixOrigin.fromValue(segment.get(DWORD, suffixOriginOffset));

				long validLifetimeOffset = suffixOriginOffset + DWORD.byteSize();
				row.validLifetime = segment.get(DWORD, validLifetimeOffset) & 0xFFFFFFFFL;

				long preferredLifetimeOffset = validLifetimeOffset + DWORD.byteSize();
				row.preferredLifetime = segment.get(DWORD, preferredLifetimeOffset) & 0xFFFFFFFFL;

				long onLinkPrefixLengthOffset = preferredLifetimeOffset + DWORD.byteSize();
				row.onLinkPrefixLength = segment.get(BYTE, onLinkPrefixLengthOffset) & 0xFF;

				long skipAsSourceOffset = onLinkPrefixLengthOffset + BYTE.byteSize();
				row.skipAsSource = segment.get(BOOLEAN_LAYOUT, skipAsSourceOffset);

				long dadStateOffset = skipAsSourceOffset + BOOLEAN_LAYOUT.byteSize() + 2;
				row.dadState = DadState.fromValue(segment.get(DWORD, dadStateOffset));

				long scopeIdOffset = dadStateOffset + DWORD.byteSize();
				row.scopeId = segment.get(DWORD, scopeIdOffset) & 0xFFFFFFFFL;

				// 创建时间戳（Windows FILETIME格式，100纳秒间隔自1601-01-01 UTC）
				long timestampOffset = scopeIdOffset + SCOPE_ID_LAYOUT.byteSize();
				long filetime = segment.get(DWORD64, timestampOffset);
				if (filetime != 0) {
					// 转换为Java Instant (从1601-01-01 UTC到1970-01-01 UTC的间隔)
					long windowsEpoch = 116444736000000000L; // 1601到1970的100纳秒间隔数
					long unixNanos = (filetime - windowsEpoch) * 100;
					row.creationTimestamp = Instant.ofEpochSecond(unixNanos / 1_000_000_000, unixNanos % 1_000_000_000);
				}
			} catch (UnknownHostException e) {
				throw new RuntimeException("Failed to parse IP address", e);
			}

			return row;
		}

		// 转换为Native内存
		public MemorySegment toMemorySegment(Arena arena) {
			MemorySegment segment = arena.allocate(MIB_UNICASTIPADDRESS_ROW_LAYOUT);

			// 设置地址
			byte[] addressBytes = address.getAddress();
			if (address instanceof Inet4Address) {
				// IPv4
				segment.set(WORD, 0, (short) AddressFamily.AF_INET.getValue());
				// 设置IPv4地址
				segment.set(WORD, 2, (short) 0); // sin_port
				for (int i = 0; i < 4; i++) {
					segment.set(BYTE, 4 + i, addressBytes[i]);
				}
				// sin_zero填充
				for (int i = 0; i < 8; i++) {
					segment.set(BYTE, 8 + i, (byte) 0);
				}
			} else if (address instanceof Inet6Address) {
				// IPv6
				segment.set(WORD, 0, (short) AddressFamily.AF_INET6.getValue());
				// 设置IPv6地址
				segment.set(WORD, 2, (short) 0); // sin6_port
				segment.set(DWORD, 4, 0); // sin6_flowinfo
				// sin6_addr
				for (int i = 0; i < 16; i++) {
					segment.set(BYTE, 8 + i, addressBytes[i]);
				}
				segment.set(DWORD, 24, 0); // sin6_scope_id
			}

			// 设置接口LUID
			long luidOffset = SOCKADDR_INET_LAYOUT.byteSize()+2;
			segment.set(DWORD64, luidOffset, interfaceLuid);

			// 设置接口索引
			long indexOffset = luidOffset + NET_LUID_LAYOUT.byteSize();
			segment.set(DWORD, indexOffset, interfaceIndex);

			// 设置其他字段
			long prefixOriginOffset = indexOffset + DWORD.byteSize();
			segment.set(DWORD, prefixOriginOffset, prefixOrigin.getValue());

			long suffixOriginOffset = prefixOriginOffset + DWORD.byteSize();
			segment.set(DWORD, suffixOriginOffset, suffixOrigin.getValue());

			long validLifetimeOffset = suffixOriginOffset + DWORD.byteSize();
			segment.set(DWORD, validLifetimeOffset, (int) validLifetime);

			long preferredLifetimeOffset = validLifetimeOffset + DWORD.byteSize();
			segment.set(DWORD, preferredLifetimeOffset, (int) preferredLifetime);

			long onLinkPrefixLengthOffset = preferredLifetimeOffset + DWORD.byteSize();
			segment.set(BYTE, onLinkPrefixLengthOffset, (byte) onLinkPrefixLength);

			long skipAsSourceOffset = onLinkPrefixLengthOffset + BYTE.byteSize();
			segment.set(BOOLEAN_LAYOUT, skipAsSourceOffset, skipAsSource);

			long dadStateOffset = skipAsSourceOffset + BOOLEAN_LAYOUT.byteSize()+2;
			segment.set(DWORD, dadStateOffset, dadState.getValue());

			long scopeIdOffset = dadStateOffset + DWORD.byteSize();
			segment.set(DWORD, scopeIdOffset, (int) scopeId);

			// 设置创建时间戳
			long timestampOffset = scopeIdOffset + SCOPE_ID_LAYOUT.byteSize();
			if (creationTimestamp != null) {
				long windowsEpoch = 116444736000000000L;
				long unixNanos = creationTimestamp.getEpochSecond() * 1_000_000_000L + creationTimestamp.getNano();
				long filetime = windowsEpoch + (unixNanos / 100);
				segment.set(DWORD64, timestampOffset, filetime);
			} else {
				segment.set(DWORD64, timestampOffset, 0L);
			}

			return segment;
		}

		// Getters和Setters
		public InetAddress getAddress() {
			return address;
		}

		public void setAddress(InetAddress address) {
			this.address = address;
		}

		public long getInterfaceLuid() {
			return interfaceLuid;
		}

		public void setInterfaceLuid(long interfaceLuid) {
			this.interfaceLuid = interfaceLuid;
		}

		public int getInterfaceIndex() {
			return interfaceIndex;
		}

		public void setInterfaceIndex(int interfaceIndex) {
			this.interfaceIndex = interfaceIndex;
		}

		public PrefixOrigin getPrefixOrigin() {
			return prefixOrigin;
		}

		public void setPrefixOrigin(PrefixOrigin prefixOrigin) {
			this.prefixOrigin = prefixOrigin;
		}

		public SuffixOrigin getSuffixOrigin() {
			return suffixOrigin;
		}

		public void setSuffixOrigin(SuffixOrigin suffixOrigin) {
			this.suffixOrigin = suffixOrigin;
		}

		public long getValidLifetime() {
			return validLifetime;
		}

		public void setValidLifetime(long validLifetime) {
			this.validLifetime = validLifetime;
		}

		public long getPreferredLifetime() {
			return preferredLifetime;
		}

		public void setPreferredLifetime(long preferredLifetime) {
			this.preferredLifetime = preferredLifetime;
		}

		public int getOnLinkPrefixLength() {
			return onLinkPrefixLength;
		}

		public void setOnLinkPrefixLength(int onLinkPrefixLength) {
			this.onLinkPrefixLength = onLinkPrefixLength;
		}

		public boolean isSkipAsSource() {
			return skipAsSource;
		}

		public void setSkipAsSource(boolean skipAsSource) {
			this.skipAsSource = skipAsSource;
		}

		public DadState getDadState() {
			return dadState;
		}

		public void setDadState(DadState dadState) {
			this.dadState = dadState;
		}

		public long getScopeId() {
			return scopeId;
		}

		public void setScopeId(long scopeId) {
			this.scopeId = scopeId;
		}

		public Instant getCreationTimestamp() {
			return creationTimestamp;
		}

		public void setCreationTimestamp(Instant creationTimestamp) {
			this.creationTimestamp = creationTimestamp;
		}

		@Override
		public String toString() {
			return String.format("UnicastIPAddressRow[address=%s, luid=0x%016X, index=%d, prefix=%s, suffix=%s]",
					address.getHostAddress(), interfaceLuid, interfaceIndex, prefixOrigin, suffixOrigin);
		}
	}

	/**
	 * 获取单播IP地址表
	 */
	public static List<UnicastIPAddressRow> getUnicastIpAddressTable(AddressFamily family) throws WindowsAPIException {
		try (Arena arena = Arena.ofConfined()) {
			// 分配指针来接收表
			MemorySegment tablePtrPtr = arena.allocate(POINTER);

			// 调用GetUnicastIpAddressTable
			int result = (int) GET_UNICAST_IP_ADDRESS_TABLE.invokeExact(family.getValue(), tablePtrPtr);

			if (result != NO_ERROR) {
				throw new WindowsAPIException("GetUnicastIpAddressTable failed", result);
			}

			// 获取表指针
			MemorySegment tablePtr = tablePtrPtr.get(POINTER, 0);
			if (tablePtr.equals(MemorySegment.NULL)) {
				return Collections.emptyList();
			}

			// 读取表头
			tablePtr = tablePtr.reinterpret(8);
			int numEntries = tablePtr.get(DWORD, 0);
			MemorySegment rowsPtr = tablePtr.reinterpret(8 + numEntries * MIB_UNICASTIPADDRESS_ROW_LAYOUT.byteSize())
					.asSlice(8);

			List<UnicastIPAddressRow> rows = new ArrayList<>();

			// 遍历所有行
			for (int i = 0; i < numEntries; i++) {
				MemorySegment rowPtr = rowsPtr.asSlice(i * MIB_UNICASTIPADDRESS_ROW_LAYOUT.byteSize())
						.reinterpret(MIB_UNICASTIPADDRESS_ROW_LAYOUT.byteSize());
				UnicastIPAddressRow row = UnicastIPAddressRow.fromMemorySegment(rowPtr);
				rows.add(row);
			}
			FREE_MIB_TABLE.invokeExact(tablePtr);

			return rows;
		} catch (Throwable e) {
			throw new RuntimeException("Error getting unicast IP address table", e);
		}
	}

	/**
	 * 初始化单播IP地址行
	 */
	public static void initializeUnicastIpAddressEntry(UnicastIPAddressRow row) throws WindowsAPIException {
		try (Arena arena = Arena.ofConfined()) {
			MemorySegment rowSegment = row.toMemorySegment(arena);

			int result = (int) INITIALIZE_UNICAST_IP_ADDRESS_ENTRY.invokeExact(rowSegment);

			if (result != NO_ERROR) {
				throw new WindowsAPIException("InitializeUnicastIpAddressEntry failed", result);
			}
		} catch (Throwable e) {
			throw new RuntimeException("Error initializing unicast IP address entry", e);
		}
	}

	/**
	 * 创建单播IP地址条目
	 */
	public static void createUnicastIpAddressEntry(UnicastIPAddressRow row) throws WindowsAPIException {
		try (Arena arena = Arena.ofConfined()) {
			MemorySegment rowSegment = row.toMemorySegment(arena);

			int result = (int) CREATE_UNICAST_IP_ADDRESS_ENTRY.invokeExact(rowSegment);

			if (result != NO_ERROR) {
				throw new WindowsAPIException("CreateUnicastIpAddressEntry failed", result);
			}
		} catch (Throwable e) {
			throw new RuntimeException("Error creating unicast IP address entry", e);
		}
	}

	/**
	 * 删除单播IP地址条目
	 */
	public static void deleteUnicastIpAddressEntry(UnicastIPAddressRow row) throws WindowsAPIException {
		try (Arena arena = Arena.ofConfined()) {
			MemorySegment rowSegment = row.toMemorySegment(arena);

			int result = (int) DELETE_UNICAST_IP_ADDRESS_ENTRY.invokeExact(rowSegment);

			if (result != NO_ERROR && result != ERROR_NOT_FOUND) {
				throw new WindowsAPIException("DeleteUnicastIpAddressEntry failed", result);
			}
		} catch (Throwable e) {
			throw new RuntimeException("Error deleting unicast IP address entry", e);
		}
	}

	/**
	 * 获取单播IP地址条目
	 */
	public static UnicastIPAddressRow getUnicastIpAddressEntry(UnicastIPAddressRow row) throws WindowsAPIException {
		try (Arena arena = Arena.ofConfined()) {
			MemorySegment rowSegment = row.toMemorySegment(arena);

			int result = (int) GET_UNICAST_IP_ADDRESS_ENTRY.invokeExact(rowSegment);

			if (result != NO_ERROR) {
				throw new WindowsAPIException("GetUnicastIpAddressEntry failed", result);
			}

			// 从内存段读取更新后的行
			return UnicastIPAddressRow.fromMemorySegment(rowSegment);
		} catch (Throwable e) {
			throw new RuntimeException("Error getting unicast IP address entry", e);
		}
	}

	/**
	 * 为Wintun适配器添加IP地址
	 */
	public static void addIpAddressToAdapter(long adapterLuid, InetAddress address, int prefix)
			throws WindowsAPIException, UnknownHostException {

		// 创建IP地址行
		UnicastIPAddressRow row = new UnicastIPAddressRow(address, adapterLuid);

		// 设置前缀长度
		row.setOnLinkPrefixLength(prefix);
		// 设置其他参数
		row.setPrefixOrigin(PrefixOrigin.IpPrefixOriginManual);
		row.setSuffixOrigin(SuffixOrigin.IpSuffixOriginManual);
		row.setValidLifetime(0xFFFFFFFFL); // 无限
		row.setPreferredLifetime(0xFFFFFFFFL); // 无限
		row.setSkipAsSource(false);

		// 创建IP地址条目
		createUnicastIpAddressEntry(row);
	}

	/**
	 * 获取指定接口的所有IP地址
	 */
	public static List<UnicastIPAddressRow> getIpAddressesByInterface(long interfaceLuid) throws WindowsAPIException {
		List<UnicastIPAddressRow> allAddresses = new ArrayList<>();

		// 获取IPv4地址
		try {
			List<UnicastIPAddressRow> ipv4Addresses = getUnicastIpAddressTable(AddressFamily.AF_INET);
			allAddresses.addAll(ipv4Addresses.stream().filter(row -> row.getInterfaceLuid() == interfaceLuid)
					.collect(Collectors.toList()));
		} catch (Exception e) {
			// 忽略错误，继续获取IPv6地址
		}

		// 获取IPv6地址
		try {
			List<UnicastIPAddressRow> ipv6Addresses = getUnicastIpAddressTable(AddressFamily.AF_INET6);
			allAddresses.addAll(ipv6Addresses.stream().filter(row -> row.getInterfaceLuid() == interfaceLuid)
					.collect(Collectors.toList()));
		} catch (Exception e) {
			// 忽略错误
		}

		return allAddresses;
	}

	/**
	 * 测试方法
	 */
	public static void main(String[] args) {
		try {
			System.out.println("=== Windows IP Address Manager Test ===");

			// 获取所有IPv4地址
			System.out.println("\nIPv4 Addresses:");
			List<UnicastIPAddressRow> ipv4Addresses = getUnicastIpAddressTable(AddressFamily.AF_INET);
			for (UnicastIPAddressRow row : ipv4Addresses) {
				System.out.println("  " + row);
			}

			// 获取所有IPv6地址
			System.out.println("\nIPv6 Addresses:");
			List<UnicastIPAddressRow> ipv6Addresses = getUnicastIpAddressTable(AddressFamily.AF_INET6);
			for (UnicastIPAddressRow row : ipv6Addresses) {
				System.out.println("  " + row);
			}

			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 工具方法：将IP地址字符串转换为字节数组
	 */
	public static byte[] ipStringToBytes(String ipAddress) throws UnknownHostException {
		return InetAddress.getByName(ipAddress).getAddress();
	}

	/**
	 * 工具方法：将字节数组转换为IP地址字符串
	 */
	public static String bytesToIpString(byte[] bytes) throws UnknownHostException {
		return InetAddress.getByAddress(bytes).getHostAddress();
	}
}