/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package etcdv3

import (
	etcd "github.com/dubbogo/gost/database/kv/etcd/v3"

	perrors "github.com/pkg/errors"
)

import (
	"github.com/apache/dubbo-go/common/logger"
)

const (
	// ConnDelay connection delay
	ConnDelay = 3
	// MaxFailTimes max failure times
	MaxFailTimes = 15
)

// ValidateClient validates client and sets options
func ValidateClient(container clientFacade, opts ...etcd.Option) error {
	options := &etcd.Options{}

	for _, opt := range opts {
		opt(options)
	}

	lock := container.ClientLock()
	lock.Lock()
	defer lock.Unlock()

	// new Client
	if container.Client() == nil || container.Client().GetRawClient() == nil {
		newClient, err := etcd.NewClient(options.Name, options.Endpoints, options.Timeout, options.Heartbeat)
		if err != nil {
			logger.Warnf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}",
				options.Name, options.Endpoints, options.Timeout, err)
			return perrors.WithMessagef(err, "new client (address:%+v)", options.Endpoints)
		}
		container.SetClient(newClient)
	}
	return nil
}

func NewServiceDiscoveryClient(opts ...etcd.Option) *etcd.Client {
	options := &etcd.Options{
		Heartbeat: 1, // default heartbeat
	}
	for _, opt := range opts {
		opt(options)
	}

	client, err := etcd.NewClient(options.Name, options.Endpoints, options.Timeout, options.Heartbeat)
	if err != nil {
		logger.Errorf("new etcd client (name{%s}, etcd addresses{%v}, timeout{%d}) = error{%v}",
			options.Name, options.Endpoints, options.Timeout, err)
	}
	return client
}
