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

import (
	log "github.com/dubbogo/gost/log/logger"
)

import (
	"dubbo.apache.org/dubbo-go/v3/common/constant"
	"dubbo.apache.org/dubbo-go/v3/config"
	"dubbo.apache.org/dubbo-go/v3/config_center"
	"dubbo.apache.org/dubbo-go/v3/global"
	"dubbo.apache.org/dubbo-go/v3/graceful_shutdown"
	"dubbo.apache.org/dubbo-go/v3/logger"
	"dubbo.apache.org/dubbo-go/v3/metadata"
	"dubbo.apache.org/dubbo-go/v3/metrics"
	"dubbo.apache.org/dubbo-go/v3/otel/trace"
	"dubbo.apache.org/dubbo-go/v3/protocol"
	"dubbo.apache.org/dubbo-go/v3/registry"
)

type InstanceOptions struct {
	Application    *global.ApplicationConfig         `validate:"required" yaml:"application" json:"application,omitempty" property:"application"`
	Protocols      map[string]*global.ProtocolConfig `validate:"required" yaml:"protocols" json:"protocols" property:"protocols"`
	Registries     map[string]*global.RegistryConfig `yaml:"registries" json:"registries" property:"registries"`
	ConfigCenter   *global.CenterConfig              `yaml:"config-center" json:"config-center,omitempty"`
	MetadataReport *global.MetadataReportConfig      `yaml:"metadata-report" json:"metadata-report,omitempty" property:"metadata-report"`
	Provider       *global.ProviderConfig            `yaml:"provider" json:"provider" property:"provider"`
	Consumer       *global.ConsumerConfig            `yaml:"consumer" json:"consumer" property:"consumer"`
	Metrics        *global.MetricsConfig             `yaml:"metrics" json:"metrics,omitempty" property:"metrics"`
	Otel           *global.OtelConfig                `yaml:"otel" json:"otel,omitempty" property:"otel"`
	Logger         *global.LoggerConfig              `yaml:"logger" json:"logger,omitempty" property:"logger"`
	Shutdown       *global.ShutdownConfig            `yaml:"shutdown" json:"shutdown,omitempty" property:"shutdown"`
	// todo(DMwangnima): router feature would be supported in the future
	//Router              []*RouterConfig                   `yaml:"router" json:"router,omitempty" property:"router"`
	EventDispatcherType string                 `default:"direct" yaml:"event-dispatcher-type" json:"event-dispatcher-type,omitempty"`
	CacheFile           string                 `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"`
	Custom              *global.CustomConfig   `yaml:"custom" json:"custom,omitempty" property:"custom"`
	Profiles            *global.ProfilesConfig `yaml:"profiles" json:"profiles,omitempty" property:"profiles"`
	TLSConfig           *global.TLSConfig      `yaml:"tls_config" json:"tls_config,omitempty" property:"tls_config"`
}

func defaultInstanceOptions() *InstanceOptions {
	return &InstanceOptions{
		Application:    global.DefaultApplicationConfig(),
		Protocols:      make(map[string]*global.ProtocolConfig),
		Registries:     make(map[string]*global.RegistryConfig),
		ConfigCenter:   global.DefaultCenterConfig(),
		MetadataReport: global.DefaultMetadataReportConfig(),
		Provider:       global.DefaultProviderConfig(),
		Consumer:       global.DefaultConsumerConfig(),
		Metrics:        global.DefaultMetricsConfig(),
		Otel:           global.DefaultOtelConfig(),
		Logger:         global.DefaultLoggerConfig(),
		Shutdown:       global.DefaultShutdownConfig(),
		Custom:         global.DefaultCustomConfig(),
		Profiles:       global.DefaultProfilesConfig(),
		TLSConfig:      global.DefaultTLSConfig(),
	}
}

func (rc *InstanceOptions) init(opts ...InstanceOption) error {
	for _, opt := range opts {
		opt(rc)
	}

	// remaining procedure is like RootConfig.Init() without RootConfig.Start()
	// tasks of RootConfig.Start() would be decomposed to Client and Server
	rcCompat := compatRootConfig(rc)
	if err := rcCompat.Logger.Init(); err != nil { // init default logger
		return err
	}
	if err := rcCompat.ConfigCenter.Init(rcCompat); err != nil {
		log.Infof("[Config Center] Config center doesn't start")
		log.Debugf("config center doesn't start because %s", err)
	} else {
		if err = rcCompat.Logger.Init(); err != nil { // init logger using config from config center again
			return err
		}
	}

	if err := rcCompat.Application.Init(); err != nil {
		return err
	}

	// init user define
	if err := rcCompat.Custom.Init(); err != nil {
		return err
	}

	// init protocol
	protocols := rcCompat.Protocols
	if len(protocols) <= 0 {
		protocol := &config.ProtocolConfig{}
		protocols = make(map[string]*config.ProtocolConfig, 1)
		protocols[constant.Dubbo] = protocol
		rcCompat.Protocols = protocols
	}
	for _, protocol := range protocols {
		if err := protocol.Init(); err != nil {
			return err
		}
	}

	// init registry
	registries := rcCompat.Registries
	if registries != nil {
		for _, reg := range registries {
			if err := reg.Init(); err != nil {
				return err
			}
		}
	}

	if err := rcCompat.MetadataReport.Init(rcCompat); err != nil {
		return err
	}
	if err := rcCompat.Metrics.Init(rcCompat); err != nil {
		return err
	}
	if err := rcCompat.Otel.Init(rcCompat.Application); err != nil {
		return err
	}

	routers := rcCompat.Router
	if len(routers) > 0 {
		for _, r := range routers {
			if err := r.Init(); err != nil {
				return err
			}
		}
		rcCompat.Router = routers
	}

	// provider、consumer must last init
	if err := rcCompat.Provider.Init(rcCompat); err != nil {
		return err
	}
	if err := rcCompat.Consumer.Init(rcCompat); err != nil {
		return err
	}
	if err := rcCompat.Shutdown.Init(); err != nil {
		return err
	}
	config.SetRootConfig(*rcCompat)

	return nil
}

func (rc *InstanceOptions) Prefix() string {
	return constant.Dubbo
}

func (rc *InstanceOptions) CloneApplication() *global.ApplicationConfig {
	if rc.Application == nil {
		return nil
	}
	return rc.Application.Clone()
}

func (rc *InstanceOptions) CloneProtocols() map[string]*global.ProtocolConfig {
	if rc.Protocols == nil {
		return nil
	}
	protocols := make(map[string]*global.ProtocolConfig, len(rc.Protocols))
	for k, v := range rc.Protocols {
		protocols[k] = v.Clone()
	}
	return protocols
}

func (rc *InstanceOptions) CloneRegistries() map[string]*global.RegistryConfig {
	if rc.Registries == nil {
		return nil
	}
	registries := make(map[string]*global.RegistryConfig, len(rc.Registries))
	for k, v := range rc.Registries {
		registries[k] = v.Clone()
	}
	return registries
}

func (rc *InstanceOptions) CloneConfigCenter() *global.CenterConfig {
	if rc.ConfigCenter == nil {
		return nil
	}
	return rc.ConfigCenter.Clone()
}

func (rc *InstanceOptions) CloneMetadataReport() *global.MetadataReportConfig {
	if rc.MetadataReport == nil {
		return nil
	}
	return rc.MetadataReport.Clone()
}

func (rc *InstanceOptions) CloneProvider() *global.ProviderConfig {
	if rc.Provider == nil {
		return nil
	}
	return rc.Provider.Clone()
}

func (rc *InstanceOptions) CloneConsumer() *global.ConsumerConfig {
	if rc.Consumer == nil {
		return nil
	}
	return rc.Consumer.Clone()
}

func (rc *InstanceOptions) CloneMetrics() *global.MetricsConfig {
	if rc.Metrics == nil {
		return nil
	}
	return rc.Metrics.Clone()
}

func (rc *InstanceOptions) CloneOtel() *global.OtelConfig {
	if rc.Otel == nil {
		return nil
	}
	return rc.Otel.Clone()
}

func (rc *InstanceOptions) CloneLogger() *global.LoggerConfig {
	if rc.Logger == nil {
		return nil
	}
	return rc.Logger.Clone()
}

func (rc *InstanceOptions) CloneShutdown() *global.ShutdownConfig {
	if rc.Shutdown == nil {
		return nil
	}
	return rc.Shutdown.Clone()
}

func (rc *InstanceOptions) CloneCustom() *global.CustomConfig {
	if rc.Custom == nil {
		return nil
	}
	return rc.Custom.Clone()
}

func (rc *InstanceOptions) CloneProfiles() *global.ProfilesConfig {
	if rc.Profiles == nil {
		return nil
	}
	return rc.Profiles.Clone()
}

func (rc *InstanceOptions) CloneTLSConfig() *global.TLSConfig {
	if rc.TLSConfig == nil {
		return nil
	}
	return rc.TLSConfig.Clone()
}

type InstanceOption func(*InstanceOptions)

func WithOrganization(organization string) InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.Organization = organization
	}
}

func WithName(name string) InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.Name = name
	}
}

func WithModule(module string) InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.Module = module
	}
}

func WithGroup(group string) InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.Group = group
	}
}

func WithVersion(version string) InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.Version = version
	}
}

func WithOwner(owner string) InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.Owner = owner
	}
}

func WithEnvironment(environment string) InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.Environment = environment
	}
}

func WithRemoteMetadata() InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.MetadataType = constant.RemoteMetadataStorageType
	}
}

func WithTag(tag string) InstanceOption {
	return func(opts *InstanceOptions) {
		opts.Application.Tag = tag
	}
}

func WithProtocol(opts ...protocol.Option) InstanceOption {
	proOpts := protocol.NewOptions(opts...)

	return func(insOpts *InstanceOptions) {
		if insOpts.Protocols == nil {
			insOpts.Protocols = make(map[string]*global.ProtocolConfig)
		}
		insOpts.Protocols[proOpts.ID] = proOpts.Protocol
	}
}

func WithRegistry(opts ...registry.Option) InstanceOption {
	regOpts := registry.NewOptions(opts...)

	return func(insOpts *InstanceOptions) {
		if insOpts.Registries == nil {
			insOpts.Registries = make(map[string]*global.RegistryConfig)
		}
		insOpts.Registries[regOpts.ID] = regOpts.Registry
	}
}

// WithTracing otel configuration, currently only supports tracing
func WithTracing(opts ...trace.Option) InstanceOption {
	traceOpts := trace.NewOptions(opts...)

	return func(insOpts *InstanceOptions) {
		insOpts.Otel.TracingConfig = traceOpts.Otel.TracingConfig
	}
}

func WithConfigCenter(opts ...config_center.Option) InstanceOption {
	configOpts := config_center.NewOptions(opts...)

	return func(cfg *InstanceOptions) {
		cfg.ConfigCenter = configOpts.Center
	}
}

func WithMetadataReport(opts ...metadata.Option) InstanceOption {
	metadataOpts := metadata.NewOptions(opts...)

	return func(cfg *InstanceOptions) {
		cfg.MetadataReport = metadataOpts.Metadata
	}
}

func WithMetrics(opts ...metrics.Option) InstanceOption {
	metricOpts := metrics.NewOptions(opts...)

	return func(cfg *InstanceOptions) {
		cfg.Metrics = metricOpts.Metrics
	}
}

func WithLogger(opts ...logger.Option) InstanceOption {
	loggerOpts := logger.NewOptions(opts...)

	return func(cfg *InstanceOptions) {
		cfg.Logger = loggerOpts.Logger
	}
}

func WithShutdown(opts ...graceful_shutdown.Option) InstanceOption {
	sdOpts := graceful_shutdown.NewOptions(opts...)

	return func(insOpts *InstanceOptions) {
		insOpts.Shutdown = sdOpts.Shutdown
	}
}

// todo(DMwangnima): enumerate specific EventDispatcherType
//func WithEventDispatcherType(typ string) InstanceOption {
//	return func(cfg *InstanceOptions) {
//		cfg.EventDispatcherType = typ
//	}
//}

//func WithCacheFile(file string) InstanceOption {
//	return func(cfg *InstanceOptions) {
//		cfg.CacheFile = file
//	}
//}

//func WithCustom(opts ...global.CustomOption) InstanceOption {
//	cusCfg := new(global.CustomConfig)
//	for _, opt := range opts {
//		opt(cusCfg)
//	}
//
//	return func(cfg *InstanceOptions) {
//		cfg.Custom = cusCfg
//	}
//}

//func WithProfiles(opts ...global.ProfilesOption) InstanceOption {
//	proCfg := new(global.ProfilesConfig)
//	for _, opt := range opts {
//		opt(proCfg)
//	}
//
//	return func(cfg *InstanceOptions) {
//		cfg.Profiles = proCfg
//	}
//}

//func WithTLS(opts ...global.TLSOption) InstanceOption {
//	tlsCfg := new(global.TLSConfig)
//	for _, opt := range opts {
//		opt(tlsCfg)
//	}
//
//	return func(cfg *InstanceOptions) {
//		cfg.TLSConfig = tlsCfg
//	}
//}
