package discover

import (
	"fmt"

	"github.com/hashicorp/consul/api"
)

type ConsulConfig struct {
	Client                         *api.Client `json:"client"`                         // consul client
	ConsulAddress                  string      `json:"consulAddress"`                  // consul 服务地址:IP+port
	ServiceId                      string      `json:"serviceId"`                      // 服务ID
	ServiceName                    string      `json:"serviceName"`                    // 服务名称
	ServiceIP                      string      `json:"serviceIP"`                      // 服务IP
	ServicePort                    int         `json:"servicePort"`                    // 服务端口
	Tags                           []string    `json:"tags"`                           // 服务标签列表
	DeregisterCriticalServiceAfter int         `json:"deregisterCriticalServiceAfter"` // 指定与服务关联的检查应在此时间之后注销
	Interval                       int         `json:"interval"`                       // 指定运行此检查的频率
	Timeout                        int         `json:"timeout"`                        // 在脚本、HTTP、TCP 或 gRPC 检查的情况下指定传出连接的超时时间
}

func NewConsulConfig(consulAddress string,
	serviceId string,
	serviceName string,
	serviceIP string,
	servicePort int,
	tags []string,
	deregisterCriticalServiceAfter int,
	interval int,
	timeout int) (*ConsulConfig, error) {
	// 1.consul配置
	config := api.DefaultConfig()
	config.Address = consulAddress
	// 2.client
	client, err := api.NewClient(config)
	if err != nil {
		return nil, err
	}
	return &ConsulConfig{
		Client:                         client,
		ConsulAddress:                  consulAddress,
		ServiceId:                      serviceId,
		ServiceName:                    serviceName,
		ServiceIP:                      serviceIP,
		ServicePort:                    servicePort,
		Tags:                           tags,
		DeregisterCriticalServiceAfter: deregisterCriticalServiceAfter,
		Interval:                       interval,
		Timeout:                        timeout,
	}, nil

}

// ServiceRegister 服务注册
func (cf *ConsulConfig) ServiceRegister() (err error) {
	// 注册器
	reg := &api.AgentServiceRegistration{
		ID:      cf.ServiceId,
		Name:    cf.ServiceName,
		Address: cf.ServiceIP,
		Port:    cf.ServicePort,
		Tags:    cf.Tags,
		Check: &api.AgentServiceCheck{
			Interval:                       fmt.Sprintf("%vs", cf.Interval),                                  // 健康检查间隔
			HTTP:                           fmt.Sprintf("http://%v:%v/health", cf.ServiceIP, cf.ServicePort), // HTTP 支持，执行健康检查的地址，service 会传到 Health.Check 函数中
			Timeout:                        fmt.Sprintf("%vs", cf.Timeout),                                   // 健康检查超时时间
			DeregisterCriticalServiceAfter: fmt.Sprintf("%vs", cf.DeregisterCriticalServiceAfter),            // 注销时间，相当于过期时间
			Notes:                          "Consul check service health status.",
		},
	}
	// 注册服务
	err = cf.Client.Agent().ServiceRegister(reg)
	if err != nil {
		return err
	}
	return nil
}

// ServiceDeregister 服务注销
func (cf *ConsulConfig) ServiceDeregister() error {
	return cf.Client.Agent().ServiceDeregister(cf.ServiceId)
}

// ServiceDiscover 服务发现
func (cf *ConsulConfig) ServiceDiscover(service string, tags []string, q *api.QueryOptions) ([]*api.CatalogService, *api.QueryMeta, error) {
	return cf.Client.Catalog().ServiceMultipleTags(service, tags, q)
}
