/*
 * 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 (
	"fmt"
)

import (
	gxset "github.com/dubbogo/gost/container/set"
	gxpage "github.com/dubbogo/gost/hash/page"
)

const DefaultPageSize = 100

// ServiceDiscovery is the interface that wraps common operations of Service Discovery
type ServiceDiscovery interface {
	fmt.Stringer

	// Destroy will destroy the service discovery.
	// If the discovery cannot be destroyed, it will return an error.
	Destroy() error

	// Register will register an instance of ServiceInstance to registry
	Register(instance ServiceInstance) error

	// Update will update the data of the instance in registry
	Update(instance ServiceInstance) error

	// Unregister will unregister this instance from registry
	Unregister(instance ServiceInstance) error

	// GetDefaultPageSize will return the default page size
	GetDefaultPageSize() int

	// GetServices will return the all service names.
	GetServices() *gxset.HashSet

	// GetInstances will return all service instances with serviceName
	GetInstances(serviceName string) []ServiceInstance

	// GetInstancesByPage will return a page containing instances of ServiceInstance
	// with the serviceName the page will start at offset
	GetInstancesByPage(serviceName string, offset int, pageSize int) gxpage.Pager

	// GetHealthyInstancesByPage will return a page containing instances of ServiceInstance.
	// The param healthy indices that the instance should be healthy or not.
	// The page will start at offset
	GetHealthyInstancesByPage(serviceName string, offset int, pageSize int, healthy bool) gxpage.Pager

	// GetRequestInstances gets all instances by the specified service names
	GetRequestInstances(serviceNames []string, offset int, requestedSize int) map[string]gxpage.Pager

	// AddListener adds a new ServiceInstancesChangedListenerImpl
	// see addServiceInstancesChangedListener in Java
	AddListener(listener ServiceInstancesChangedListener) error
}

type ServiceDiscoveryRegistry interface {
	// RegisterService register service instance use metadata info
	RegisterService() error
	// UnRegisterService unregister service instance
	UnRegisterService() error
}
