package etcd

import (
	"common/config"
	"context"
	"go.etcd.io/etcd/client/v3"
	"time"
)

var instance *Client

type Client struct {
	cli *clientv3.Client
}

// Init 初始化
func Init(cfg *config.EtcdConfig) error {
	client, err := clientv3.New(clientv3.Config{
		Endpoints:   cfg.Endpoints,
		DialTimeout: 5 * time.Second,
	})
	instance = &Client{
		cli: client,
	}
	return err
}

// Close 关闭
func Close() error {
	if instance != nil && instance.cli != nil {
		return instance.cli.Close()
	}
	return nil
}

func GetClient() *Client {
	return instance
}

// Get 获取数据
func (c *Client) Get(key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	return c.cli.Get(ctx, key, opts...)
}

// Put 创建数据
func (c *Client) Put(key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	return c.cli.Put(ctx, key, val, opts...)
}

// Grant 创建租约
func (c *Client) Grant(ttl int64) (*clientv3.LeaseGrantResponse, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	return c.cli.Grant(ctx, ttl)
}

// KeepAlive 保活租约
func (c *Client) KeepAlive(id clientv3.LeaseID) (<-chan *clientv3.LeaseKeepAliveResponse, error) {
	return c.cli.KeepAlive(context.Background(), id)
}

// Revoke 撤销租约
func (c *Client) Revoke(id clientv3.LeaseID) (*clientv3.LeaseRevokeResponse, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	return c.cli.Revoke(ctx, id)
}

// Watch 监听数据
func (c *Client) Watch(key string, opts ...clientv3.OpOption) clientv3.WatchChan {
	return c.cli.Watch(context.Background(), key, opts...)
}
