/*
 * 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 registry

import (
	"path"
	"strings"
	"time"
)

import (
	"github.com/apache/dubbo-go/common"
	gxzookeeper "github.com/dubbogo/gost/database/kv/zk"
)

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

const (
	rootPath = "/dubbo"
)

func init() {
	var _ Loader = new(ZookeeperRegistryLoad)
}

// ZookeeperRegistryLoad load dubbo apis from zookeeper registry
type ZookeeperRegistryLoad struct {
	zkName  string
	client  *gxzookeeper.ZookeeperClient
	Address string
	cluster string
}

func newZookeeperRegistryLoad(address, cluster string) (Loader, error) {
	newClient, err := gxzookeeper.NewZookeeperClient("zkClient", strings.Split(address, ","), false, gxzookeeper.WithZkTimeOut(15*time.Second))
	if err != nil {
		logger.Warnf("newZookeeperClient error:%v", err)
		return nil, err
	}

	r := &ZookeeperRegistryLoad{
		Address: address,
		client:  newClient,
		cluster: cluster,
	}

	return r, nil
}

// nolint
func (crl *ZookeeperRegistryLoad) GetCluster() (string, error) {
	return crl.cluster, nil
}

// LoadAllServices load all services from zookeeper registry
func (crl *ZookeeperRegistryLoad) LoadAllServices() ([]*common.URL, error) {
	children, err := crl.client.GetChildren(rootPath)
	if err != nil {
		logger.Errorf("[zookeeper registry] get zk children error:%v", err)
		return nil, err
	}
	var urls []*common.URL
	for _, _interface := range children {
		providerStr := path.Join(rootPath, "/", _interface, "/", "providers")
		urlStrs, err := crl.client.GetChildren(providerStr)
		if err != nil {
			logger.Errorf("[zookeeper registry] get zk children \"%s\" error:%v", providerStr, err)
			return nil, err
		}
		for _, url := range urlStrs {
			dubboURL, err := common.NewURL(url)
			if err != nil {
				logger.Warnf("[zookeeper registry] transfer zk info to url error:%v", err)
				continue
			}
			urls = append(urls, dubboURL)
		}
	}
	return urls, nil
}
