// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package memcache provides a minimally compatible interface for
// google.golang.org/appengine/memcache
// and stores the data in Redis (e.g., via Cloud Memorystore).
package memcache

import (
	"bytes"
	"context"
	"encoding/gob"
	"encoding/json"
	"errors"
	"time"

	"github.com/gomodule/redigo/redis"
)

var ErrCacheMiss = errors.New("memcache: cache miss")

func New(addr string) *Client {
	const maxConns = 20

	pool := redis.NewPool(func() (redis.Conn, error) {
		return redis.Dial("tcp", addr)
	}, maxConns)

	return &Client{
		pool: pool,
	}
}

type Client struct {
	pool *redis.Pool
}

type CodecClient struct {
	client *Client
	codec  Codec
}

type Item struct {
	Key        string
	Value      []byte
	Object     interface{}   // Used with Codec.
	Expiration time.Duration // Read-only.
}

func (c *Client) WithCodec(codec Codec) *CodecClient {
	return &CodecClient{
		c, codec,
	}
}

func (c *Client) Delete(ctx context.Context, key string) error {
	conn, err := c.pool.GetContext(ctx)
	if err != nil {
		return err
	}
	defer conn.Close()

	_, err = conn.Do("DEL", key)
	return err
}

func (c *CodecClient) Delete(ctx context.Context, key string) error {
	return c.client.Delete(ctx, key)
}

func (c *Client) Set(ctx context.Context, item *Item) error {
	if item.Value == nil {
		return errors.New("nil item value")
	}
	return c.set(ctx, item.Key, item.Value, item.Expiration)
}

func (c *CodecClient) Set(ctx context.Context, item *Item) error {
	if item.Object == nil {
		return errors.New("nil object value")
	}
	b, err := c.codec.Marshal(item.Object)
	if err != nil {
		return err
	}
	return c.client.set(ctx, item.Key, b, item.Expiration)
}

func (c *Client) set(ctx context.Context, key string, value []byte, expiration time.Duration) error {
	conn, err := c.pool.GetContext(ctx)
	if err != nil {
		return err
	}
	defer conn.Close()

	if expiration == 0 {
		_, err := conn.Do("SET", key, value)
		return err
	}

	// NOTE(cbro): redis does not support expiry in units more granular than a second.
	exp := int64(expiration.Seconds())
	if exp == 0 {
		// Redis doesn't allow a zero expiration, delete the key instead.
		_, err := conn.Do("DEL", key)
		return err
	}

	_, err = conn.Do("SETEX", key, exp, value)
	return err
}

// Get gets the item.
func (c *Client) Get(ctx context.Context, key string) ([]byte, error) {
	conn, err := c.pool.GetContext(ctx)
	if err != nil {
		return nil, err
	}
	defer conn.Close()

	b, err := redis.Bytes(conn.Do("GET", key))
	if err == redis.ErrNil {
		err = ErrCacheMiss
	}
	return b, err
}

func (c *CodecClient) Get(ctx context.Context, key string, v interface{}) error {
	b, err := c.client.Get(ctx, key)
	if err != nil {
		return err
	}
	return c.codec.Unmarshal(b, v)
}

var (
	Gob  = Codec{gobMarshal, gobUnmarshal}
	JSON = Codec{json.Marshal, json.Unmarshal}
)

type Codec struct {
	Marshal   func(interface{}) ([]byte, error)
	Unmarshal func([]byte, interface{}) error
}

func gobMarshal(v interface{}) ([]byte, error) {
	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(v); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

func gobUnmarshal(data []byte, v interface{}) error {
	return gob.NewDecoder(bytes.NewBuffer(data)).Decode(v)
}
