package eventstream

import (
	"context"
	"fmt"
	"log"
	"regexp"
	"strings"

	"code.justin.tv/eventbus/admin-cli/internal/client"
	"code.justin.tv/eventbus/admin-cli/internal/environment"

	"code.justin.tv/eventbus/controlplane/rpc"

	"github.com/spf13/cobra"
)

var (
	freqsEnv string
)

func init() {
	getAlarmFrequenciesEventStreamsCommand.Flags().StringVarP(&freqsEnv, "environment", "e", "", "environment to query")
	getAlarmFrequenciesEventStreamsCommand.MarkFlagRequired("environment")
}

var getAlarmFrequenciesEventStreamsCommand = &cobra.Command{
	Use:   "frequencies",
	Short: "List the alarm frequencies of  event streams",
	Run: func(cmd *cobra.Command, args []string) {
		ctx := context.Background()
		config, err := environment.Resolve()
		if err != nil {
			log.Fatal("Error resolving runtime environment: ", err.Error())
		}

		c, err := client.NewEventStreams(config)
		if err != nil {
			log.Fatal("Error creating event streams client: ", err.Error())
		}

		events, err := c.List(ctx, &rpc.ListEventStreamsReq{})
		if err != nil {
			log.Fatal("Error fetching event streams: ", err.Error())
		}

		frequencies := map[string][]string{
			highFrequencyKey:    {},
			lowFrequencyKey:     {},
			veryLowFrequencyKey: {},
		}

		for _, event := range events.GetEventStreams() {
			if event.Environment != freqsEnv {
				continue
			}

			stats, err := c.GetStats(ctx, &rpc.GetEventStreamStatsReq{
				EventType:   event.GetEventType(),
				Environment: freqsEnv,
			})
			if err != nil {
				log.Println("Could not fetch stats for " + event.GetEventType())
				continue
			}

			if stats.GetMinEventsPerMinute().GetValue() >= highFrequencyThreshold {
				frequencies[highFrequencyKey] = append(frequencies[highFrequencyKey], event.GetEventType())
			} else if stats.GetMinEventsPerMinute().GetValue() >= lowFrequencyThreshold {
				frequencies[lowFrequencyKey] = append(frequencies[lowFrequencyKey], event.GetEventType())
			} else {
				frequencies[veryLowFrequencyKey] = append(frequencies[veryLowFrequencyKey], event.GetEventType())
			}
		}

		for freq, events := range frequencies {
			fmt.Println(outputTerraform(freq, events))
		}
	},
}

func outputTerraform(freq string, events []string) string {
	var sb strings.Builder

	switch freq {
	case highFrequencyKey:
		sb.WriteString("high_frequency_events = {\n")
	case lowFrequencyKey:
		sb.WriteString("low_frequency_events = {\n")
	default:
		sb.WriteString("very_low_frequency_events = {\n")
	}

	r := regexp.MustCompile(`[A-Z][^A-Z]*`)
	for _, event := range events {
		var snakeCase string
		for _, eventNameComponent := range r.FindAllString(event, -1) {
			snakeCase += strings.ToLower(eventNameComponent) + "_"
		}
		snakeCase = strings.TrimRight(snakeCase, "_")
		sb.WriteString(fmt.Sprintf("  %s = \"%s\"\n", snakeCase, event))
	}

	sb.WriteString("}\n")
	return sb.String()
}
