/*
Package redis implements the redis related operations to support Skia perf, specifically
for the query UI. It includes two types of methods:
 1. The methods to interact with the Redis instances management on GCP.
    Those are done by using cloud.google.com/go/redis/apiv1
 2. The methods to interact with the Redis data on an Redis instance.
    Those are done by using github.com/redis/go-redis.
*/
package redis

import (
	"context"
	"errors"
	"fmt"
	"time"

	gcp_redis "cloud.google.com/go/redis/apiv1"
	rpb "cloud.google.com/go/redis/apiv1/redispb"
	"github.com/redis/go-redis/v9"
	"go.skia.org/infra/go/cache"
	"go.skia.org/infra/go/sklog"
)

// Format for the redis instance name in GCP.
const redisInstanceNameFormat = "projects/%s/locations/%s/instances/%s"

// RedisConfig contains properties of a redis instance.
type RedisConfig struct {
	// The GCP Project of the Redis instance
	Project string `json:"project,omitempty" optional:"true"`

	// The Zone (Region) of the Redis instance.
	Zone string `json:"zone,omitempty" optional:"true"`

	// The name of the Redis instance.
	Instance string `json:"instance,omitempty" optional:"true"`

	// Cache expiration for the given keys.
	CacheExpirationInMinutes int `json:"cache_expiration_minutes,omitempty" optional:"true"`
}

// redisCache implements RedisWrapper
type redisCache struct {
	gcpClient   *gcp_redis.CloudRedisClient
	config      *RedisConfig
	redisClient *redis.Client
}

// NewRedisCache returns an initialized RedisCache
func NewRedisCache(ctx context.Context, gcpClient *gcp_redis.CloudRedisClient, config *RedisConfig) (*redisCache, error) {
	r := &redisCache{
		gcpClient: gcpClient,
		config:    config,
	}
	err := r.init(ctx)
	return r, err
}

// init initializes the Redis cache connections.
func (r *redisCache) init(ctx context.Context) error {
	instanceName := fmt.Sprintf(redisInstanceNameFormat, r.config.Project, r.config.Zone, r.config.Instance)
	instanceRequest := &rpb.GetInstanceRequest{
		Name: instanceName,
	}
	instance, err := r.gcpClient.GetInstance(ctx, instanceRequest)
	if err != nil {
		sklog.Errorf("Error getting redis instance information %v", err)
		return err
	}
	opts := &redis.Options{
		Addr: fmt.Sprintf("%s:%d", instance.Host, instance.Port),
	}
	r.redisClient = redis.NewClient(opts)
	return nil
}

func (r *redisCache) Add(key string) {
	panic(errors.ErrUnsupported)
}

// Exists returns true  if the key is found in the cache.
func (r *redisCache) Exists(key string) bool {
	err := r.redisClient.Exists(context.Background(), key).Err()
	return err == nil
}

// SetValue sets the value for the key in the redis cache.
func (r *redisCache) SetValue(ctx context.Context, key string, value string) error {
	expirationMinutes := r.config.CacheExpirationInMinutes
	if expirationMinutes < 1 {
		// Default to 1 hour cache expiration.
		expirationMinutes = 60
	}
	expiryDuration := time.Minute * time.Duration(expirationMinutes)
	return r.redisClient.Set(ctx, key, value, expiryDuration).Err()
}

// GetValue returns the value for the key in the redis cache.
func (r *redisCache) GetValue(ctx context.Context, key string) (string, error) {
	value, err := r.redisClient.Get(ctx, key).Result()
	if err == redis.Nil {
		sklog.Infof("Key %s not found", key)
		return "", nil
	}

	return value, err
}

// Confirm we implement the interface.
var _ cache.Cache = (*redisCache)(nil)
