package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"sync"
	"sync/atomic"
	"time"

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

var (
	idContext    int32 = 0
	contextStore       = new(sync.Map)
)

func getContextID() int {
	return int(atomic.AddInt32(&idContext, 1))
}

func messageIncoming(mes *Message) {
	mData := mes.Data()
	if mData.String("type", "") == "event" {
		// event
	} else {
		command := mData.String("command", "")
		switch command {
		case "method":
			log.Println("METHOD")
			randomNum, check := checkBigInt(mes, "random_num")
			if !check {
				//randomNum = big.NewInt(1000000)
				return
			}
			message := mData.String(
				"message",
				"Демонстрация работы алгоритмов шифрования Диффи-Хеллмана и Эль-Гамаля на эллиптических кривых и атаки на них.",
			)
			deadline := time.Now().Add(time.Duration(mData.Int("deadline_sec", 600)) * time.Second)
			contextID := getContextID()
			mes.SendResponse(json.Map{
				"context_id": contextID,
				"random_num": randomNum,
				"deadline":   deadline.Unix(),
				"message":    message,
			})
			ctx, cancel := context.WithDeadline(mes.Client().Context(), deadline)
			contextStore.Store(contextID, cancel)
			go func() {
				cl := mes.Client()
				for e := range MethodCurve(randomNum, message, ctx, contextID) {
					cl.SendSingle(e.Map())
				}
				log.Println("CONTEXT_STOPPED", contextID)
			}()
		case "context_stop":
			contextID := mData.Int32("context_id", -1)
			if contextID == -1 {
				mes.SendResponse(json.Map{
					"error": true,
					"text":  "Ожидается context_id",
				})
				return
			}
			cancel, check := contextStore.LoadAndDelete(contextID)
			if !check {
				mes.SendResponse(json.Map{
					"error": true,
					"text":  fmt.Sprintf("контекст [ %s ] не найден", contextID),
				})
				return
			}
			cancel.(context.CancelFunc)()
			mes.SendResponse(json.Map{
				"context_id": contextID,
				"text":       "Контекст остановлен",
			})
		case "exit":
			os.Exit(0)
		default:
			if mes.IsResponsable() {
				mes.SendResponse(json.Map{
					"error": true,
					"text":  fmt.Sprintf("команда [ %s ] не найдена", command),
				})
			}
		}
	}

	mData.LogPretty()
}
