// Copyright 2023 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0

package jobqueue

import (
	"context"
	"fmt"
	"sync"
)

func NewCounterRunnableFromMap(data map[string]any) (*CounterRunnable, error) {

	// in go numbers are float64 by default
	floatCount, ok := data["count"].(float64)
	if !ok {
		return nil, fmt.Errorf("%w: Invalid count: %v", ErrInvalidData, data["count"])
	}

	count := int(floatCount)

	return &CounterRunnable{Count: count}, nil
}

// CounterResult is a result of a counter
type CounterResult struct {
	Count int
}

// CounterRunnable is a runnable that counts
type CounterRunnable struct {
	Count int `json:"count" yaml:"count"`
	mu    sync.Mutex
}

// GetCount returns the current count
func (c *CounterRunnable) GetCount() int {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.Count
}

// Run runs the counter
func (c *CounterRunnable) Run(_ context.Context) (RunResult[CounterResult], error) {
	c.mu.Lock()
	defer c.mu.Unlock()

	c.Count++

	return RunResult[CounterResult]{
		Status: ResultStatusSuccess,
		Data: CounterResult{
			Count: c.Count,
		},
	}, nil
}

func (c *CounterRunnable) GetType() string {
	return "counter"
}

func (c *CounterRunnable) GetPersistence() RunnableImport {

	data := JSONMap{
		"count": c.Count,
	}

	return RunnableImport{
		Type: c.GetType(),
		Data: data,
	}
}