using System.Runtime.InteropServices;
using System.Text;
namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
static uint GalaxyCommodityRebuildSelfTest()
{
uint passed=0;var memory=Platform.Allocate(0x40000);if(memory==0)return 0;
try
{
var expectedImage=memory-0x5FDB000;var service=memory+0x1000;var enumeration=memory+0x3058;var definitions=memory+0x5000;
var enumBuckets=memory+0x7000;var defBuckets=memory+0x8000;var enumNode=memory+0x9000;var defNode=memory+0xA000;var name=memory+0xB000;
var systemBuckets=memory+0xC000;var marketBuckets=memory+0xD000;const uint uid=0xF0000001,marketId=103;
void Map(nuint header,nuint buckets,ulong count){Write(header,buckets);Write(header+8,17UL);Write(header+0x18,count);for(nuint i=0;i<17;i++)Write(buckets+i*8,buckets+i*8);}
void Insert32(nuint buckets,nuint node,uint id){var sentinel=buckets+(nuint)(GalaxyCommodityHash(id)%17)*8;Write(node,Pointer(sentinel));Write(node+8,id);Write(sentinel,node);}
void Insert64(nuint buckets,nuint node,ulong id){var sentinel=buckets+(nuint)(GalaxyCommoditySystemHash(id)%17)*8;Write(node,Pointer(sentinel));Write(node+8,id);Write(sentinel,node);}
Write(enumeration,expectedImage+0x5241A18);Write(enumeration-0x58,expectedImage+0x52418E8);Write(enumeration-0x50,expectedImage+0x5241918);Write(enumeration-0x48,memory+0x6000);Write(enumeration+0x50,(byte)1);
Write(service+0x48,definitions+0x58);Write(service+0x50,enumeration);Map(enumeration+0x58,enumBuckets,1);Insert32(enumBuckets,enumNode,uid);
Write(enumNode+0xC,100f);Write(enumNode+0x10,marketId);Write(enumNode+0x14,1u);Map(definitions+0x1B8,defBuckets,1);Insert32(defBuckets,defNode,uid);
var text=Encoding.UTF8.GetBytes("Actual commodity");Write(defNode+0x18,name);Write(name,(ulong)text.Length);for(nuint i=0;i<(nuint)text.Length;i++)Write(name+0x14+i,text[(int)i]);
var source=service-0x58;Write(source+0x190,(byte)1);Write(source+0x191,(byte)0);Write(source+0x194,10f);
const ulong first=9007199254740993,second=9007199254740994,third=9007199254740995,fourth=9007199254740996;
var ids=new[]{first,second,third,fourth};Map(source+0x118,systemBuckets,4);Map(source+0xF8,marketBuckets,5);
var vectors=new nuint[4];var marketNodes=new nuint[5];var data=new nuint[5];
for(nuint i=0;i<4;i++)
{var node=memory+0xE000+i*0x100;vectors[i]=memory+0x10000+i*0x100;Insert64(systemBuckets,node,ids[i]);Write(node+0x40,i==0?2UL:1UL);Write(node+0x48,vectors[i]);}
void Quote(int index,uint buy,uint sell,uint flags,bool present=true)
{
var node=marketNodes[index];Write(node+0x18,present?1UL:0UL);Write(node+0x20,8UL);Write(node+0x28,data[index]);Write(data[index],0UL);
if(!present)return;var slot=(nuint)(GalaxyCommodityHash(marketId)&7);Write(data[index],1UL<<(int)slot);var row=data[index]+8+slot*0x10;Write(row,marketId);Write(row+4,buy);Write(row+8,sell);Write(row+0xC,flags);
}
for(nuint i=0;i<5;i++){marketNodes[i]=memory+0x12000+i*0x100;data[i]=memory+0x14000+i*0x100;Insert64(marketBuckets,marketNodes[i],1000+(ulong)i);}
void Station(nuint row,ulong id){Write(row,id);Write(row+0x10,10f);Write(row+0x14,(byte)0);Write(row+0x17,(byte)1);}
Station(vectors[0],1000);Station(vectors[0]+0x20,1001);Station(vectors[1],1002);Station(vectors[2],1003);Station(vectors[3],1004);
Quote(0,50,0,2);Quote(1,75,0,2);Quote(2,75,0,2);Quote(3,0,200,1);Quote(4,0,0,0,false);
GalaxyCommodityBalanceRow[] Copy(out Func<bool> stable)=>CopyGalaxyCommodityRebuild(new GalaxyCommodityCopy(),service,enumeration,definitions,expectedImage,uid,out stable);
var before=Platform.ReadBytes(memory,0x40000);var result=Copy(out var captured);
if(result.Length==4&&result.Single(r=>r.systemAddress==first).balance==-1&&result.Single(r=>r.systemAddress==second).balance==-.5f&&result.Single(r=>r.systemAddress==third).balance==1&&result.Single(r=>r.systemAddress==fourth).balance==0)passed|=1;
if(captured()&&Platform.ReadBytes(memory,0x40000).AsSpan().SequenceEqual(before))passed|=2;
Write(source+0x190,(byte)0);Write(vectors[0]+0x14,(byte)1);Write(vectors[0]+0x34,(byte)1);var filtered=Copy(out _);var filters=filtered.All(r=>r.systemAddress!=first);
Write(source+0x190,(byte)1);Write(vectors[0]+0x14,(byte)0);Write(vectors[0]+0x34,(byte)0);Write(vectors[1]+0x10,10.01f);filters&=Copy(out _).All(r=>r.systemAddress!=second);Write(vectors[1]+0x10,10f);
Write(source+0x191,(byte)1);Write(vectors[0]+0x17,(byte)0);Write(vectors[0]+0x37,(byte)0);filters&=Copy(out _).All(r=>r.systemAddress!=first);Write(source+0x191,(byte)0);if(filters)passed|=4;
// Exact original sparse-table collision and wrap probing, not UID
// indexing: the stored id is103 (hash slot7), while UID is high-bit.
var slot=(nuint)(GalaxyCommodityHash(marketId)&7);var following=(slot+1)&7;Write(marketNodes[2]+0x18,2UL);Write(data[2],(1UL<<(int)slot)|(1UL<<(int)following));
var collision=marketId+1;while((GalaxyCommodityHash(collision)&7)!=(uint)slot)collision++;
Write(data[2]+8+slot*0x10,collision);var moved=data[2]+8+following*0x10;Write(moved,marketId);Write(moved+4,75u);Write(moved+8,0u);Write(moved+0xC,2u);
if(Copy(out _).Single(r=>r.systemAddress==second).balance==-.5f)passed|=8;Quote(2,75,0,2);
Quote(3,0,200,5);var ignored=Copy(out _).Single(r=>r.systemAddress==third).balance==0;Quote(3,0,200,1);Quote(4,0,0,3);ignored&=Copy(out _).Single(r=>r.systemAddress==fourth).balance==-1;Quote(4,0,0,0,false);if(ignored)passed|=16;
bool Reject(){try{Copy(out _);return false;}catch(InvalidDataException){return true;}}
Write(data[0],0UL);var invalid=Reject();Quote(0,50,0,2);Write(vectors[0]+0x10,float.NaN);invalid&=Reject();Write(vectors[0]+0x10,10f);Write(enumNode+0x10,0u);invalid&=Reject();Write(enumNode+0x10,marketId);if(invalid)passed|=32;
result=Copy(out captured);Write(enumNode+0xC,101f);var changed=!captured()&&result.Single(r=>r.systemAddress==second).balance==-.5f;Write(enumNode+0xC,100f);Copy(out captured);Write(enumeration+0x50,(byte)0);changed&=!captured()&&Reject();Write(enumeration+0x50,(byte)1);if(changed)passed|=64;
// UID0/FFFFFFFE remain real keys; market id still comes from its row.
var exact=true;foreach(var actual in new[]{0u,uint.MaxValue-1})
{Map(enumeration+0x58,enumBuckets,1);Insert32(enumBuckets,enumNode,actual);Map(definitions+0x1B8,defBuckets,1);Insert32(defBuckets,defNode,actual);exact&=CopyGalaxyCommodityRebuild(new GalaxyCommodityCopy(),service,enumeration,definitions,expectedImage,actual,out _).Length==4;}
if(exact)passed|=128;return passed;
}
catch{return passed;}
finally{Platform.Free(memory);}
}
#if PLUGIN_NAVIGATION
[UnmanagedCallersOnly(EntryPoint="XFENavigationGalaxyCommodityRebuildSelfTest")]
internal static uint ExportGalaxyCommodityRebuildSelfTest()=>RunTest(GalaxyCommodityRebuildSelfTest);
#endif
}
using System.Runtime.InteropServices;
using System.Text;
namespace XFEEDToolBox.Plugin;
internal static unsafe partial class Navigation
{
static uint GalaxyCommodityRebuildSelfTest()
{
uint passed=0;var memory=Platform.Allocate(0x40000);if(memory==0)return 0;
try
{
var expectedImage=memory-0x5FDB000;var service=memory+0x1000;var enumeration=memory+0x3058;var definitions=memory+0x5000;
var enumBuckets=memory+0x7000;var defBuckets=memory+0x8000;var enumNode=memory+0x9000;var defNode=memory+0xA000;var name=memory+0xB000;
var systemBuckets=memory+0xC000;var marketBuckets=memory+0xD000;const uint uid=0xF0000001,marketId=103;
void Map(nuint header,nuint buckets,ulong count){Write(header,buckets);Write(header+8,17UL);Write(header+0x18,count);for(nuint i=0;i<17;i++)Write(buckets+i*8,buckets+i*8);}
void Insert32(nuint buckets,nuint node,uint id){var sentinel=buckets+(nuint)(GalaxyCommodityHash(id)%17)*8;Write(node,Pointer(sentinel));Write(node+8,id);Write(sentinel,node);}
void Insert64(nuint buckets,nuint node,ulong id){var sentinel=buckets+(nuint)(GalaxyCommoditySystemHash(id)%17)*8;Write(node,Pointer(sentinel));Write(node+8,id);Write(sentinel,node);}
Write(enumeration,expectedImage+0x5241A18);Write(enumeration-0x58,expectedImage+0x52418E8);Write(enumeration-0x50,expectedImage+0x5241918);Write(enumeration-0x48,memory+0x6000);Write(enumeration+0x50,(byte)1);
Write(service+0x48,definitions+0x58);Write(service+0x50,enumeration);Map(enumeration+0x58,enumBuckets,1);Insert32(enumBuckets,enumNode,uid);
Write(enumNode+0xC,100f);Write(enumNode+0x10,marketId);Write(enumNode+0x14,1u);Map(definitions+0x1B8,defBuckets,1);Insert32(defBuckets,defNode,uid);
var text=Encoding.UTF8.GetBytes("Actual commodity");Write(defNode+0x18,name);Write(name,(ulong)text.Length);for(nuint i=0;i<(nuint)text.Length;i++)Write(name+0x14+i,text[(int)i]);
var source=service-0x58;Write(source+0x190,(byte)1);Write(source+0x191,(byte)0);Write(source+0x194,10f);
const ulong first=9007199254740993,second=9007199254740994,third=9007199254740995,fourth=9007199254740996;
var ids=new[]{first,second,third,fourth};Map(source+0x118,systemBuckets,4);Map(source+0xF8,marketBuckets,5);
var vectors=new nuint[4];var marketNodes=new nuint[5];var data=new nuint[5];
for(nuint i=0;i<4;i++)
{var node=memory+0xE000+i*0x100;vectors[i]=memory+0x10000+i*0x100;Insert64(systemBuckets,node,ids[i]);Write(node+0x40,i==0?2UL:1UL);Write(node+0x48,vectors[i]);}
void Quote(int index,uint buy,uint sell,uint flags,bool present=true)
{
var node=marketNodes[index];Write(node+0x18,present?1UL:0UL);Write(node+0x20,8UL);Write(node+0x28,data[index]);Write(data[index],0UL);
if(!present)return;var slot=(nuint)(GalaxyCommodityHash(marketId)&7);Write(data[index],1UL<<(int)slot);var row=data[index]+8+slot*0x10;Write(row,marketId);Write(row+4,buy);Write(row+8,sell);Write(row+0xC,flags);
}
for(nuint i=0;i<5;i++){marketNodes[i]=memory+0x12000+i*0x100;data[i]=memory+0x14000+i*0x100;Insert64(marketBuckets,marketNodes[i],1000+(ulong)i);}
void Station(nuint row,ulong id){Write(row,id);Write(row+0x10,10f);Write(row+0x14,(byte)0);Write(row+0x17,(byte)1);}
Station(vectors[0],1000);Station(vectors[0]+0x20,1001);Station(vectors[1],1002);Station(vectors[2],1003);Station(vectors[3],1004);
Quote(0,50,0,2);Quote(1,75,0,2);Quote(2,75,0,2);Quote(3,0,200,1);Quote(4,0,0,0,false);
GalaxyCommodityBalanceRow[] Copy(out Func<bool> stable)=>CopyGalaxyCommodityRebuild(new GalaxyCommodityCopy(),service,enumeration,definitions,expectedImage,uid,out stable);
var before=Platform.ReadBytes(memory,0x40000);var result=Copy(out var captured);
if(result.Length==4&&result.Single(r=>r.systemAddress==first).balance==-1&&result.Single(r=>r.systemAddress==second).balance==-.5f&&result.Single(r=>r.systemAddress==third).balance==1&&result.Single(r=>r.systemAddress==fourth).balance==0)passed|=1;
if(captured()&&Platform.ReadBytes(memory,0x40000).AsSpan().SequenceEqual(before))passed|=2;
Write(source+0x190,(byte)0);Write(vectors[0]+0x14,(byte)1);Write(vectors[0]+0x34,(byte)1);var filtered=Copy(out _);var filters=filtered.All(r=>r.systemAddress!=first);
Write(source+0x190,(byte)1);Write(vectors[0]+0x14,(byte)0);Write(vectors[0]+0x34,(byte)0);Write(vectors[1]+0x10,10.01f);filters&=Copy(out _).All(r=>r.systemAddress!=second);Write(vectors[1]+0x10,10f);
Write(source+0x191,(byte)1);Write(vectors[0]+0x17,(byte)0);Write(vectors[0]+0x37,(byte)0);filters&=Copy(out _).All(r=>r.systemAddress!=first);Write(source+0x191,(byte)0);if(filters)passed|=4;
// Exact original sparse-table collision and wrap probing, not UID
// indexing: the stored id is103 (hash slot7), while UID is high-bit.
var slot=(nuint)(GalaxyCommodityHash(marketId)&7);var following=(slot+1)&7;Write(marketNodes[2]+0x18,2UL);Write(data[2],(1UL<<(int)slot)|(1UL<<(int)following));
var collision=marketId+1;while((GalaxyCommodityHash(collision)&7)!=(uint)slot)collision++;
Write(data[2]+8+slot*0x10,collision);var moved=data[2]+8+following*0x10;Write(moved,marketId);Write(moved+4,75u);Write(moved+8,0u);Write(moved+0xC,2u);
if(Copy(out _).Single(r=>r.systemAddress==second).balance==-.5f)passed|=8;Quote(2,75,0,2);
Quote(3,0,200,5);var ignored=Copy(out _).Single(r=>r.systemAddress==third).balance==0;Quote(3,0,200,1);Quote(4,0,0,3);ignored&=Copy(out _).Single(r=>r.systemAddress==fourth).balance==-1;Quote(4,0,0,0,false);if(ignored)passed|=16;
bool Reject(){try{Copy(out _);return false;}catch(InvalidDataException){return true;}}
Write(data[0],0UL);var invalid=Reject();Quote(0,50,0,2);Write(vectors[0]+0x10,float.NaN);invalid&=Reject();Write(vectors[0]+0x10,10f);Write(enumNode+0x10,0u);invalid&=Reject();Write(enumNode+0x10,marketId);if(invalid)passed|=32;
result=Copy(out captured);Write(enumNode+0xC,101f);var changed=!captured()&&result.Single(r=>r.systemAddress==second).balance==-.5f;Write(enumNode+0xC,100f);Copy(out captured);Write(enumeration+0x50,(byte)0);changed&=!captured()&&Reject();Write(enumeration+0x50,(byte)1);if(changed)passed|=64;
// UID0/FFFFFFFE remain real keys; market id still comes from its row.
var exact=true;foreach(var actual in new[]{0u,uint.MaxValue-1})
{Map(enumeration+0x58,enumBuckets,1);Insert32(enumBuckets,enumNode,actual);Map(definitions+0x1B8,defBuckets,1);Insert32(defBuckets,defNode,actual);exact&=CopyGalaxyCommodityRebuild(new GalaxyCommodityCopy(),service,enumeration,definitions,expectedImage,actual,out _).Length==4;}
if(exact)passed|=128;return passed;
}
catch{return passed;}
finally{Platform.Free(memory);}
}
#if PLUGIN_NAVIGATION
[UnmanagedCallersOnly(EntryPoint="XFENavigationGalaxyCommodityRebuildSelfTest")]
internal static uint ExportGalaxyCommodityRebuildSelfTest()=>RunTest(GalaxyCommodityRebuildSelfTest);
#endif
}