package etcd

import (
	"context"
	"fmt"
	"strings"
	"time"

	clientv3 "go.etcd.io/etcd/client/v3"
)

// func (sd *EtcdService) StopWatch() {
// 	sd.cancelWatch()
// 	sd.wgWatch.Wait()
// }

// func (sd *EtcdService) WatchServer(sm ServerManager) {
// 	sd.wgWatch.Wait()
// 	sd.wgWatch.Add(1)
// 	go sd.watchServer(sm)
// }

// func (sd *EtcdService) watchServer(sm ServerManager) {
// 	defer func() {
// 		sd.wgWatch.Done()
// 	}()

// 	ctx, cancelWatch := context.WithCancel(sd.coreCtx)
// 	chW := sd.EtcdCli.Watch(ctx, "servers/", clientv3.WithPrefix())
// 	sd.cancelWatch = cancelWatch

// 	go func() {

// 		for {
// 			select {
// 			case wResp, ok := <-chW:
// 				if wResp.Err() != nil {
// 					fmt.Printf("etcd watcher response error: %s", wResp.Err())
// 					// logger.Warnf("etcd watcher response error: %s", wResp.Err())
// 				}
// 				if !ok {
// 					// logger.Error("etcd watcher died")
// 					return
// 				}
// 				for _, ev := range wResp.Events {

// 					switch ev.Type {
// 					case clientv3.EventTypePut:
// 						s, _ := PutServer(ev.Kv.Key, ev.Kv.Value)
// 						if s != nil {
// 							sm.AddServer(s)
// 						}
// 					case clientv3.EventTypeDelete:
// 						id, _ := DeleteServer(ev.Kv.Key, ev.Kv.Value)
// 						if len(id) > 0 {
// 							sm.DeleteServer(id)
// 						}
// 					}
// 				}

// 			case <-sd.coreCtx.Done():
// 				return
// 			case <-sd.chExitEtcd:
// 				cancelWatch()
// 				return
// 			}
// 		}
// 	}()
// }

func (sd *EtcdService) SyncServer() ([]*Server, error) {
	keys, err := sd.EtcdCli.Get(
		context.TODO(),
		"servers/gate/",
		clientv3.WithPrefix(),
		//clientv3.WithKeysOnly(),
	)
	if err != nil {
		return nil, err
	}

	var lst []*Server
	for _, kv := range keys.Kvs {
		fmt.Println("sync server", string(kv.Key), string(kv.Value))

		if s, err := ParseEtcdServer(kv.Value); err == nil {
			lst = append(lst, s)
		}
	}
	return lst, nil
}

func (sd *EtcdService) Get(k string) (map[string]string, error) {
	ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
	key := "servers/" + k
	keys, err := sd.EtcdCli.Get(
		ctx,
		key,
		clientv3.WithPrefix(),
	)
	if err != nil {
		return nil, err
	}

	maps := make(map[string]string)
	for _, kv := range keys.Kvs {
		ik := string(kv.Key)
		v := string(kv.Value)
		fmt.Println("EtcdService Get", ik, v)

		nik := strings.TrimRight(ik, "/")
		n := strings.LastIndexByte(nik, '/')
		var nk string
		if n >= 0 {
			nk = nik[n+1:]
		} else {
			nk = nik
		}

		maps[nk] = v
	}
	return maps, nil
}
