package main

import (
	"errors"
	"fmt"
	"github.com/gogf/gf/util/guid"
	"sparrow/pkg/models"
	"sparrow/pkg/server"
)

// SaveProduct 如果product.ID为空则会添加，否则更新相应产品信息
func (r *Registry) SaveProduct(product *models.Product, reply *models.Product) error {
	db, err := getDB()
	product.RecordId = guid.S()
	if err != nil {
		return err
	}

	if product.ID == 0 {
		// create product
		err = db.Save(product).Error
		if err != nil {
			return err
		}

		key, err := r.keygen.GenRandomKey(product.RecordId)
		if err != nil {
			return err
		}

		product.ProductKey = key
	}

	err = db.Save(product).Error
	if err != nil {
		return err
	}

	cache := getCache()
	cacheKey := fmt.Sprintf("Product:%v", product.ID)
	if _, ok := cache.Get(cacheKey); ok {
		cache.Delete(cacheKey)
	}

	setProduct(reply, product)

	return nil
}

// DelProduct 删除一个产品
func (r *Registry) DelProduct(product *models.Product, reply *models.Product) error {
	// clear cache
	cache := getCache()
	key := fmt.Sprintf("Product:%v", product.ID)
	if _, ok := cache.Get(key); ok {
		cache.Delete(key)
	}
	// clear db
	db, err := getDB()
	if err != nil {
		return err
	}
	err = db.Delete(product).Error
	if err != nil {
		server.Log.Errorf("delete product error: %s", err.Error())
		return errDbActFailt
	}
	return nil
}

// FindProduct will find product by specified ID
func (r *Registry) FindProduct(id string, reply *models.Product) error {
	db, err := getDB()
	if err != nil {
		return err
	}

	cache := getCache()
	cacheKey := fmt.Sprintf("Product:%v", id)
	if cacheValue, ok := cache.Get(cacheKey); ok {
		product := cacheValue.(*models.Product)
		setProduct(reply, product)
	} else {
		err = db.First(reply, "record_id = ?", id).Error
		if err != nil {
			return err
		}
		var storage models.Product
		storage = *reply
		cache.Set(cacheKey, &storage)
	}

	return nil
}

// ValidateProduct try to validate the given product key.
// if success, it will reply the corresponding product
func (r *Registry) ValidateProduct(key string, reply *models.Product) error {
	db, err := getDB()
	if err != nil {
		return err
	}

	id, err := r.keygen.DecodeIDFromRandomKey(key)
	if err != nil {
		return err
	}

	cache := getCache()
	cacheKey := fmt.Sprintf("Product:%v", id)
	if cacheValue, ok := cache.Get(cacheKey); ok {
		product := cacheValue.(*models.Product)
		setProduct(reply, product)
	} else {
		err = db.First(reply, "record_id = ?", id).Error
		if err != nil {
			return err
		}
		var storage models.Product
		storage = *reply
		cache.Set(cacheKey, &storage)
	}

	if reply.ProductKey != key {
		return errors.New("product key not match")
	}

	return nil
}
