package daemon // import "github.com/docker/docker/daemon"

import (
	"context"
	"encoding/json"
	"fmt"
	"strconv"

	"github.com/containerd/log"
	"github.com/docker/docker/api/types/events"
	"github.com/hashicorp/go-multierror"
	"github.com/mitchellh/copystructure"

	"github.com/docker/docker/daemon/config"
)

// reloadTxn is used to defer side effects of a config reload.
type reloadTxn struct {
	onCommit, onRollback []func() error
}

// OnCommit defers a function to be called when a config reload is being finalized.
// The error returned from cb is purely informational.
func (tx *reloadTxn) OnCommit(cb func() error) {
	tx.onCommit = append(tx.onCommit, cb)
}

// OnRollback defers a function to be called when a config reload is aborted.
// The error returned from cb is purely informational.
func (tx *reloadTxn) OnRollback(cb func() error) {
	tx.onCommit = append(tx.onRollback, cb)
}

func (tx *reloadTxn) run(cbs []func() error) error {
	tx.onCommit = nil
	tx.onRollback = nil

	var res *multierror.Error
	for _, cb := range cbs {
		res = multierror.Append(res, cb())
	}
	return res.ErrorOrNil()
}

// Commit calls all functions registered with OnCommit.
// Any errors returned by the functions are collated into a
// *github.com/hashicorp/go-multierror.Error value.
func (tx *reloadTxn) Commit() error {
	return tx.run(tx.onCommit)
}

// Rollback calls all functions registered with OnRollback.
// Any errors returned by the functions are collated into a
// *github.com/hashicorp/go-multierror.Error value.
func (tx *reloadTxn) Rollback() error {
	return tx.run(tx.onRollback)
}

// Reload modifies the live daemon configuration from conf.
// conf is assumed to be a validated configuration.
//
// These are the settings that Reload changes:
// - Platform runtime
// - Daemon debug log level
// - Daemon max concurrent downloads
// - Daemon max concurrent uploads
// - Daemon max download attempts
// - Daemon shutdown timeout (in seconds)
// - Cluster discovery (reconfigure and restart)
// - Daemon labels
// - Insecure registries
// - Registry mirrors
// - Daemon live restore
func (daemon *Daemon) Reload(conf *config.Config) error {
	daemon.configReload.Lock()
	defer daemon.configReload.Unlock()
	copied, err := copystructure.Copy(daemon.config().Config)
	if err != nil {
		return err
	}
	newCfg := &configStore{
		Config: copied.(config.Config),
	}

	attributes := map[string]string{}

	// Ideally reloading should be transactional: the reload either completes
	// successfully, or the daemon config and state are left untouched. We use a
	// two-phase commit protocol to achieve this. Any fallible reload operation is
	// split into two phases. The first phase performs all the fallible operations
	// and mutates the newCfg copy. The second phase atomically swaps newCfg into
	// the live daemon configuration and executes any commit functions the first
	// phase registered to apply the side effects. If any first-phase returns an
	// error, the reload transaction is rolled back by discarding newCfg and
	// executing any registered rollback functions.

	var txn reloadTxn
	for _, reload := range []func(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error{
		daemon.reloadPlatform,
		daemon.reloadDebug,
		daemon.reloadMaxConcurrentDownloadsAndUploads,
		daemon.reloadMaxDownloadAttempts,
		daemon.reloadShutdownTimeout,
		daemon.reloadFeatures,
		daemon.reloadLabels,
		daemon.reloadRegistryConfig,
		daemon.reloadLiveRestore,
		daemon.reloadNetworkDiagnosticPort,
	} {
		if err := reload(&txn, newCfg, conf, attributes); err != nil {
			if rollbackErr := txn.Rollback(); rollbackErr != nil {
				return multierror.Append(nil, err, rollbackErr)
			}
			return err
		}
	}

	jsonString, _ := json.Marshal(&struct {
		*config.Config
		config.Proxies `json:"proxies"`
	}{
		Config: &newCfg.Config,
		Proxies: config.Proxies{
			HTTPProxy:  config.MaskCredentials(newCfg.HTTPProxy),
			HTTPSProxy: config.MaskCredentials(newCfg.HTTPSProxy),
			NoProxy:    config.MaskCredentials(newCfg.NoProxy),
		},
	})
	log.G(context.TODO()).Infof("Reloaded configuration: %s", jsonString)
	daemon.configStore.Store(newCfg)
	daemon.LogDaemonEventWithAttributes(events.ActionReload, attributes)
	return txn.Commit()
}

func marshalAttributeSlice(v []string) string {
	if v == nil {
		return "[]"
	}
	b, err := json.Marshal(v)
	if err != nil {
		panic(err) // Should never happen as the input type is fixed.
	}
	return string(b)
}

// reloadDebug updates configuration with Debug option
// and updates the passed attributes
func (daemon *Daemon) reloadDebug(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	// update corresponding configuration
	if conf.IsValueSet("debug") {
		newCfg.Debug = conf.Debug
	}
	// prepare reload event attributes with updatable configurations
	attributes["debug"] = strconv.FormatBool(newCfg.Debug)
	return nil
}

// reloadMaxConcurrentDownloadsAndUploads updates configuration with max concurrent
// download and upload options and updates the passed attributes
func (daemon *Daemon) reloadMaxConcurrentDownloadsAndUploads(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	// We always "reset" as the cost is lightweight and easy to maintain.
	newCfg.MaxConcurrentDownloads = config.DefaultMaxConcurrentDownloads
	newCfg.MaxConcurrentUploads = config.DefaultMaxConcurrentUploads

	if conf.IsValueSet("max-concurrent-downloads") && conf.MaxConcurrentDownloads != 0 {
		newCfg.MaxConcurrentDownloads = conf.MaxConcurrentDownloads
	}
	if conf.IsValueSet("max-concurrent-uploads") && conf.MaxConcurrentUploads != 0 {
		newCfg.MaxConcurrentUploads = conf.MaxConcurrentUploads
	}
	txn.OnCommit(func() error {
		if daemon.imageService != nil {
			daemon.imageService.UpdateConfig(
				newCfg.MaxConcurrentDownloads,
				newCfg.MaxConcurrentUploads,
			)
		}
		return nil
	})

	// prepare reload event attributes with updatable configurations
	attributes["max-concurrent-downloads"] = strconv.Itoa(newCfg.MaxConcurrentDownloads)
	attributes["max-concurrent-uploads"] = strconv.Itoa(newCfg.MaxConcurrentUploads)
	log.G(context.TODO()).Debug("Reset Max Concurrent Downloads: ", attributes["max-concurrent-downloads"])
	log.G(context.TODO()).Debug("Reset Max Concurrent Uploads: ", attributes["max-concurrent-uploads"])
	return nil
}

// reloadMaxDownloadAttempts updates configuration with max concurrent
// download attempts when a connection is lost and updates the passed attributes
func (daemon *Daemon) reloadMaxDownloadAttempts(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	// We always "reset" as the cost is lightweight and easy to maintain.
	newCfg.MaxDownloadAttempts = config.DefaultDownloadAttempts
	if conf.IsValueSet("max-download-attempts") && conf.MaxDownloadAttempts != 0 {
		newCfg.MaxDownloadAttempts = conf.MaxDownloadAttempts
	}

	// prepare reload event attributes with updatable configurations
	attributes["max-download-attempts"] = strconv.Itoa(newCfg.MaxDownloadAttempts)
	log.G(context.TODO()).Debug("Reset Max Download Attempts: ", attributes["max-download-attempts"])
	return nil
}

// reloadShutdownTimeout updates configuration with daemon shutdown timeout option
// and updates the passed attributes
func (daemon *Daemon) reloadShutdownTimeout(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	// update corresponding configuration
	if conf.IsValueSet("shutdown-timeout") {
		newCfg.ShutdownTimeout = conf.ShutdownTimeout
		log.G(context.TODO()).Debugf("Reset Shutdown Timeout: %d", newCfg.ShutdownTimeout)
	}

	// prepare reload event attributes with updatable configurations
	attributes["shutdown-timeout"] = strconv.Itoa(newCfg.ShutdownTimeout)
	return nil
}

// reloadLabels updates configuration with engine labels
// and updates the passed attributes
func (daemon *Daemon) reloadLabels(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	// update corresponding configuration
	if conf.IsValueSet("labels") {
		newCfg.Labels = conf.Labels
	}

	// prepare reload event attributes with updatable configurations
	attributes["labels"] = marshalAttributeSlice(newCfg.Labels)
	return nil
}

// reloadRegistryConfig updates the configuration with registry options
// and updates the passed attributes.
func (daemon *Daemon) reloadRegistryConfig(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	// Update corresponding configuration.
	if conf.IsValueSet("allow-nondistributable-artifacts") {
		newCfg.ServiceOptions.AllowNondistributableArtifacts = conf.AllowNondistributableArtifacts
	}
	if conf.IsValueSet("insecure-registries") {
		newCfg.ServiceOptions.InsecureRegistries = conf.InsecureRegistries
	}
	if conf.IsValueSet("registry-mirrors") {
		newCfg.ServiceOptions.Mirrors = conf.Mirrors
	}

	commit, err := daemon.registryService.ReplaceConfig(newCfg.ServiceOptions)
	if err != nil {
		return err
	}
	txn.OnCommit(func() error { commit(); return nil })

	attributes["allow-nondistributable-artifacts"] = marshalAttributeSlice(newCfg.ServiceOptions.AllowNondistributableArtifacts)
	attributes["insecure-registries"] = marshalAttributeSlice(newCfg.ServiceOptions.InsecureRegistries)
	attributes["registry-mirrors"] = marshalAttributeSlice(newCfg.ServiceOptions.Mirrors)

	return nil
}

// reloadLiveRestore updates configuration with live restore option
// and updates the passed attributes
func (daemon *Daemon) reloadLiveRestore(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	// update corresponding configuration
	if conf.IsValueSet("live-restore") {
		newCfg.LiveRestoreEnabled = conf.LiveRestoreEnabled
	}

	// prepare reload event attributes with updatable configurations
	attributes["live-restore"] = strconv.FormatBool(newCfg.LiveRestoreEnabled)
	return nil
}

// reloadNetworkDiagnosticPort updates the network controller starting the diagnostic if the config is valid
func (daemon *Daemon) reloadNetworkDiagnosticPort(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	txn.OnCommit(func() error {
		if conf == nil || daemon.netController == nil || !conf.IsValueSet("network-diagnostic-port") ||
			conf.NetworkDiagnosticPort < 1 || conf.NetworkDiagnosticPort > 65535 {
			// If there is no config make sure that the diagnostic is off
			if daemon.netController != nil {
				daemon.netController.StopDiagnostic()
			}
			return nil
		}
		// Enable the network diagnostic if the flag is set with a valid port within the range
		log.G(context.TODO()).WithFields(log.Fields{"port": conf.NetworkDiagnosticPort, "ip": "127.0.0.1"}).Warn("Starting network diagnostic server")
		daemon.netController.StartDiagnostic(conf.NetworkDiagnosticPort)
		return nil
	})
	return nil
}

// reloadFeatures updates configuration with enabled/disabled features
func (daemon *Daemon) reloadFeatures(txn *reloadTxn, newCfg *configStore, conf *config.Config, attributes map[string]string) error {
	// update corresponding configuration
	// note that we allow features option to be entirely unset
	newCfg.Features = conf.Features

	// prepare reload event attributes with updatable configurations
	attributes["features"] = fmt.Sprintf("%v", newCfg.Features)
	return nil
}
