package main

import (
	"context"
	"sync/atomic"
	"time"

	"git.ali33.ru/fcg-xvii/curve/v2"
	"git.ali33.ru/fcg-xvii/curve/v2/tools"
	"git.ali33.ru/fcg-xvii/go-tools/containers/concurrent"
	"git.ali33.ru/fcg-xvii/go-tools/json"
)

var (
	curveStore = &CurveStore{
		List: concurrent.NewList(),
		cid:  int32(0),
	}
)

type Curve struct {
	*tools.Curve
	id int32
}

func (s *Curve) Map() json.Map {
	res := s.Curve.Map()
	res["id"] = s.id
	return res
}

func (s *Curve) MarshalJSON() ([]byte, error) {
	return s.Map().JSON(), nil
}

type CurveStore struct {
	*concurrent.List
	cid int32
}

func (s *CurveStore) APICurveInit(mes *Message) {
	mData := mes.Data()
	a, check := checkBigInt(mes, "a")
	if !check {
		return
	}
	b, check := checkBigInt(mes, "b")
	if !check {
		return
	}
	p, check := checkBigInt(mes, "p")
	if !check {
		return
	}
	ctx, _ := context.WithDeadline(
		context.Background(),
		time.Now().Add(time.Second*time.Duration(mData.Int("deadline_seconds", 30))),
	)
	c, err := curve.NewCurve(a, b, p, ctx)
	if err != nil {
		mes.SendResponse(messageError(err.Error()))
		return
	}
	cur := &Curve{
		Curve: c,
		id:    atomic.AddInt32(&s.cid, 1),
	}
	s.PushBack(cur)
	mes.SendResponse(json.Map{
		"curve": cur.Map(),
	})
}

func (s *CurveStore) APICurves(mes *Message) {
	curves := s.List.Slice()
	mes.SendResponse(json.Map{
		"curves": curves,
	})
}
