#include "crowd_decode.hpp"
#include <iostream>
#include <limits>
using namespace contextra;
static int passed=0;
static void check(bool v) {if(!v) throw std::runtime_error("CROWD contract assertion failed");++passed;}
int main() {
    CrowdRawContract c;
    check(!validateCrowdDeclaration(c));
    c.queries=2; c.logits=4; c.personSlot=2; c.headSlot=0; c.ignoredSlots={1,3};
    c.checkpointSha256=std::string(64,'a');c.onnxSha256=std::string(64,'b');c.reviewId="SYNTHETIC_TEST_ONLY";
    c.boxFormat="CXCYWH_NORMALIZED";c.scoreFormat="RAW_SIGMOID_LOGITS";
    c.selectionPolicy="GLOBAL_TOP300_THEN_MAP";
    check(validateCrowdDeclaration(c));
    for(uint32_t b=1;b<=8;++b)check(validateCrowdTensorContract(c,{b,2,4},{b,2,4},b,true,true));
    check(!validateCrowdTensorContract(c,{1,2,4},{1,2,3},1,true,true));
    check(!validateCrowdTensorContract(c,{1,2,4},{1,2,4},1,false,true));
    check(!validateCrowdTensorContract(c,{9,2,4},{9,2,4},9,true,true));
    auto bad=c;bad.personSlot=0;check(!validateCrowdDeclaration(bad));
    bad=c;bad.ignoredSlots={1};check(!validateCrowdDeclaration(bad));
    bad=c;bad.scoreFormat="PROBABILITIES";check(!validateCrowdDeclaration(bad));
    bad=c;bad.onnxSha256.clear();check(!validateCrowdDeclaration(bad));
    const std::vector<float> boxes={.5,.5,.4,.6,.2,.2,.1,.1};
    auto result=decodeCrowdFrame(c,boxes,{4,1,5,2,3,1,2,1});
    check(result.size()==4);check(result[0].classId==0);check(result[1].classId==1);
    check(std::abs(result[0].xyxy[0]-.3f)<1e-6);check(result[0].score>.99f);
    bool threw=false;try{decodeCrowdFrame(CrowdRawContract{},boxes,{});}catch(const std::invalid_argument&){threw=true;}
    check(threw);
    auto z=boxes;z[2]=0;check(decodeCrowdFrame(c,z,{4,1,5,2,3,1,2,1}).size()==2);
    z=boxes;z[0]=std::numeric_limits<float>::quiet_NaN();
    check(decodeCrowdFrame(c,z,{4,1,5,2,3,1,2,1}).size()==2);
    auto large=c;large.queries=200;
    std::vector<float> many(800,.5f),scores(800,1.f);
    check(decodeCrowdFrame(large,many,scores).size()<=300);
    std::cout<<"PASS "<<passed<<" portable CROWD assertions; SDK/GPU/model NOT RUN\n";
}
