package tools

import (
	"context"
	"log"
	"math/big"
	"testing"
	"time"

	"git.ali33.ru/fcg-xvii/go-tools/json"
)

func TestIsCurveSingular(t *testing.T) {
	t.Log(IsCurveSingular(intZero, intZero))
	t.Log(IsCurveSingular(big.NewInt(2), big.NewInt(4)))
}

func TestCurveRandom(t *testing.T) {
	a, b, p := CurveRandomParams(big.NewInt(10000000))
	t.Log(a, b, p)
	cur, _ := NewCurve(a, b)
	cur.SetP(p)
	log.Println(cur.SetGRandom(context.Background()))
	log.Println(cur.g)
}

func TestSearchP(t *testing.T) {
	min := big.NewInt(1)
	var g *big.Int
	var err error
	mmin := big.NewInt(0)
	mg := big.NewInt(0)
	for {
		ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Millisecond*50))
		if min, g, err = SearchP(min, ctx); err != nil {
			log.Println(mmin, mg)
			t.Fatal(err)
		}
		mmin, mg = min, g
		cancel()
		//log.Println(min, g)
		min = Add64(min, 1)
	}
}

func TestFormula(t *testing.T) {
	a, _ := big.NewInt(0).SetString("10", 10)
	b, _ := big.NewInt(0).SetString("15", 10)
	c, err := NewCurve(a, b)
	if err != nil {
		t.Fatal(err)
	}
	t.Log(c.FormulaString())
}

func TestSingular(t *testing.T) {
	a := big.NewInt(0)
	b := big.NewInt(0)
	c, err := NewCurve(a, b)
	if err == nil {
		t.Fatal(c.FormulaString(), ", не сингулярна")
	}
	t.Log(err)
}

func TestSearchPrime(t *testing.T) {
	a := big.NewInt(101010101010)
	b := SearchPrime(a)
	t.Log(a, b)
}

func TestBigRandom(t *testing.T) {
	for i := 0; i < 10; i++ {
		t.Log(Random(big.NewInt(15), big.NewInt(20)))
	}
}

func TestPointShow(t *testing.T) {
	p := &Point{
		y: big.NewInt(105465465463543),
	}
	t.Log(p.Show())
	t.Log(p.ShowHex())
}

func TestCurveG(t *testing.T) {
	curve, err := NewCurve(
		big.NewInt(2),
		big.NewInt(4),
	)
	if err != nil {
		t.Fatal(err)
	}
	p := SearchPrime(big.NewInt(2000000))
	log.Println("P", p)
	if err = curve.SetP(p); err != nil {
		t.Fatal(err)
	}
	if err = curve.SetGRandom(context.Background()); err != nil {
		t.Fatal(err)
	}
	t.Log("G", curve.g)
}

func TestJSON(t *testing.T) {
	p := big.NewInt(0).SetBytes([]byte{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10})
	t.Log(p)
	jm := json.Map{
		"p": p,
	}
	jm.LogPretty()
	pl := jm.Value("p", big.NewInt(0))
	log.Printf("%T %s", pl, pl)
	src := []byte(`{
        "p": "13"
	}`)
	var jjm json.Map
	json.Unmarshal(src, &jjm)
	pll, _ := big.NewInt(0).SetString(jjm.StringVal("p", ""), 10)
	log.Printf("%T %s", pll, pll)
}

func TestSplit(t *testing.T) {
	x := big.NewInt(1000)
	parts := 2
	firstOffset, lastOffset := big.NewInt(1), big.NewInt(2)
	res := Split(x, parts, firstOffset, lastOffset)
	log.Println(res)
}

func TestInt(t *testing.T) {
	x := big.NewInt(100000000)
	b := Bytes32(x)
	dx := new(big.Int).SetBytes(b)
	t.Log(x, dx, b)
}