package config

import (
	"context"
	"fmt"
	"strconv"

	"code.justin.tv/creator-collab/log"
	"code.justin.tv/creator-collab/log/errors"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ssm"
)

const (
	disableAutohostingKeySuffix = "AutohostWorker/DisableAutohosting"
)

// DynamicConfig contains config values that can be updated while the service is running.
type DynamicConfig struct {
	// Not used. This is meant to be an example of how to add future config.
	DisableAutohosting bool
}

// DynamicConfigLoader fetches dynamic config from SSM Parameter Store.
type DynamicConfigLoader struct {
	KeyPrefix string
	Logger    log.Logger
	SSMClient *ssm.SSM
}

func (l *DynamicConfigLoader) Load(ctx context.Context) DynamicConfig {
	// Initialize to defaults.
	conf := DynamicConfig{
		DisableAutohosting: false,
	}

	disableAutohostingKey := l.getParamKey(disableAutohostingKeySuffix)
	keys := []*string{
		aws.String(disableAutohostingKey),
	}
	output, err := l.SSMClient.GetParametersWithContext(ctx, &ssm.GetParametersInput{
		Names: keys,
	})
	if err != nil {
		l.Logger.Error(errors.Wrap(err, "fetching dynamic config from parameter store failed"))
		return conf
	}

	paramMap := make(map[string]string, len(keys))
	for _, param := range output.Parameters {
		if param.Name == nil || param.Value == nil {
			continue
		}
		paramMap[*param.Name] = *param.Value
	}

	if v := paramMap[disableAutohostingKey]; v != "" {
		b, err := strconv.ParseBool(v)
		if err != nil {
			l.Logger.Error(errors.Wrap(err, "parsing SSM param value failed", errors.Fields{
				"key":   disableAutohostingKey,
				"value": v,
			}))
		}
		conf.DisableAutohosting = b
	}

	return conf
}

func (l *DynamicConfigLoader) getParamKey(keySuffix string) string {
	return fmt.Sprintf("/%s/%s", l.KeyPrefix, keySuffix)
}
