package cache

import (
	"errors"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/db/queries"
	"github.com/fiskerinc/cloud-services/pkg/logger"
	"github.com/fiskerinc/cloud-services/pkg/redis"
)

// RetrieveVINs retrieves VINs from redis or from DB based on driver ID and proceeds to cache VINs
// redis keys:
//
//	driver:<ID>:cars
func RetrieveVINs(client redis.Client, db queries.CarsInterface, id string) ([]string, error) {
	var vins []string
	driverVINsKey := redis.DriverToVINsKey(id)

	// retrieve VINs from redis
	err := client.GetCache(driverVINsKey, &vins, 0)
	if err != nil && !errors.Is(err, redis.ErrNilObject) {
		logger.Warn().Err(err).Send()
	} else if len(vins) > 0 {
		return vins, nil
	}

	// if VINs not present in redis perform DB lookup
	var vehicles []common.CarToDriver
	vehicles, err = db.GetCarsForDriver(id)
	if err != nil {
		return vins, err
	}

	for _, vehicle := range vehicles {
		vins = append(vins, vehicle.VIN)
	}

	// cache drivers vehicles
	err = client.SetCache(driverVINsKey, vins, redisObjectExpire)
	if err != nil {
		return vins, err
	}

	return vins, nil
}

func RetrieveVINsAsSet(client redis.Client, db queries.CarsInterface, id string) (map[string]struct{}, error) {
	vins, err := RetrieveVINs(client, db, id)
	if err != nil {
		return nil, err
	}

	var vinsSet = make(map[string]struct{})
	for _, vin := range vins {
		vinsSet[vin] = struct{}{}
	}

	return vinsSet, nil
}
