package workers

import (
	"agent/client"
	"agent/commons/debug"
	"agent/commons/utils"
	"agent/commons/utime"
	"agent/modules/console/api"
	"context"
	"time"

	"github.com/google/uuid"
)

func InputWorker(ctx context.Context, consoleManager *ConsoleManager) {
	cl := client.ExtractClient(ctx)

	consoles := map[UUID]api.ReqeustCommands{}
	for {
		// Если клиент не авторизован, то засыпаем на 1 секунду
		if !cl.IsAuthorized() {
			utime.Sleep(1 * utime.Second)
			continue
		}
		waitCommandInterval := getWaitCommandInterval(ctx)
		if waitCommandInterval == 0 {
			// Что-то пошло не так, засыпаем на 1 секунду
			utime.Sleep(1 * utime.Second)
			debug.Log("waitCommandInterval is 0")
			continue
		}
		select {
		case <-ctx.Done():
			return
		case <-time.After(time.Second * time.Duration(waitCommandInterval)):
			if !cl.IsAuthorized() {
				continue
			}

			res, err := api.AgentConsoleInputGetList(ctx, cl, utils.MapValues(consoles)...)
			if err != nil {
				debug.Log(err)
				continue
			} else if len(res) == 0 {
				continue
			}

			// Сбрасываем старые данные по консолям
			consoles = map[UUID]api.ReqeustCommands{}

			results := map[UUID][]UUID{}
			for _, consoleInfo := range res {
				consoleUuid := consoleInfo.Uuid

				console := consoleManager.Get(consoleUuid)
				if console == nil {
					console, err = consoleManager.Open(consoleUuid)
					if err != nil {
						debug.Log(err)
						continue
					}
				}

				// Переопределение интварала получения команд из консоли
				if consoleInfo.Interval > 0 {
					cl := client.ExtractClient(ctx)
					interval := cl.Interval()
					interval.ConsoleInput = consoleInfo.Interval
					cl.SetInterval(interval)
				}

				lastCommandUuid := consoleInfo.Commands.LastUuid
				if lastCommandUuid != uuid.Nil {
					console := consoles[consoleUuid]
					console.LastCommandUuid = lastCommandUuid
					consoles[consoleUuid] = console
				}

				commands := consoleInfo.Commands.Items
				for _, command := range commands {
					if err = console.AddCommand(ctx, command); err != nil {
						debug.Log(err)
					}
					results[consoleUuid] = append(results[consoleUuid], command.Uuid)
				}
			}

			if len(results) == 0 {
				continue
			}

			if err = api.AgentConsoleInputSetProcessed(ctx, cl, results); err != nil {
				debug.Log(err)
			}
		}
	}
}

func getWaitCommandInterval(ctx context.Context) int {
	cl := client.ExtractClient(ctx)
	intervals := cl.Interval()
	waitCommandInterval := intervals.ConsoleInput
	if waitCommandInterval == 0 {
		waitCommandInterval = intervals.Next
	}
	return waitCommandInterval
}
