package main

import (
	"math/big"
	"testing"

	"github.com/consensys/gnark-crypto/ecc"
	"github.com/consensys/gnark/backend/groth16"
	"github.com/consensys/gnark/frontend"
	"github.com/consensys/gnark/frontend/cs/r1cs"
)

func TestFalsa(t *testing.T) {
	cs, _ := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &Idade{})
	pk, vk, _ := groth16.Setup(cs)
	nasc, salt := big.NewInt(2010), big.NewInt(1)
	w, _ := frontend.NewWitness(&Idade{Nasc: nasc, Ano: 2026, Salt: salt, Compr: mimcHash(nasc, salt)}, ecc.BN254.ScalarField())
	if _, err := groth16.Prove(cs, pk, w); err == nil {
		t.Fatal("16 anos gerou prova")
	}
	// idade certa, mas documento de outra pessoa (compromisso não bate)
	n2 := big.NewInt(1990)
	w2, _ := frontend.NewWitness(&Idade{Nasc: n2, Ano: 2026, Salt: salt, Compr: mimcHash(big.NewInt(2010), salt)}, ecc.BN254.ScalarField())
	if _, err := groth16.Prove(cs, pk, w2); err == nil {
		t.Fatal("documento trocado gerou prova")
	}
	// prova válida não serve para outro ano público
	w3, _ := frontend.NewWitness(&Idade{Nasc: n2, Ano: 2026, Salt: salt, Compr: mimcHash(n2, salt)}, ecc.BN254.ScalarField())
	p, err := groth16.Prove(cs, pk, w3)
	if err != nil { t.Fatal(err) }
	pubErr, _ := frontend.NewWitness(&Idade{Ano: 2000, Compr: mimcHash(n2, salt)}, ecc.BN254.ScalarField(), frontend.PublicOnly())
	if groth16.Verify(p, vk, pubErr) == nil { t.Fatal("prova aceita com dado público trocado") }
	s, s2 := big.NewInt(9000), big.NewInt(3)
	cs2, _ := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &Saldo{})
	pk2, _, _ := groth16.Setup(cs2)
	w4, _ := frontend.NewWitness(&Saldo{S: s, Salt: s2, X: 10000, Compr: mimcHash(s, s2)}, ecc.BN254.ScalarField())
	if _, err := groth16.Prove(cs2, pk2, w4); err == nil { t.Fatal("saldo baixo gerou prova") }
}
