// Copyright (C) MongoDB, Inc. 2017-present.
//
// Licensed 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

package options

import (
	"context"
	"net"
	"time"

	"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
	"github.com/mongodb/mongo-go-driver/event"
	"github.com/mongodb/mongo-go-driver/mongo/readconcern"
	"github.com/mongodb/mongo-go-driver/mongo/readpref"
	"github.com/mongodb/mongo-go-driver/mongo/writeconcern"
	"github.com/mongodb/mongo-go-driver/x/mongo/driver/topology"
	"github.com/mongodb/mongo-go-driver/x/network/connection"
	"github.com/mongodb/mongo-go-driver/x/network/connstring"
)

// ContextDialer makes new network connections
type ContextDialer interface {
	DialContext(ctx context.Context, network, address string) (net.Conn, error)
}

// SSLOpt holds client SSL options.
//
// Enabled indicates whether SSL should be enabled.
//
// ClientCertificateKeyFile specifies the file containing the client certificate and private key
// used for authentication.
//
// ClientCertificateKeyPassword provides a callback that returns a password used for decrypting the
// private key of a PEM file (if one is provided).
//
// Insecure indicates whether to skip the verification of the server certificate and hostname.
//
// CaFile specifies the file containing the certificate authority used for SSL connections.
type SSLOpt struct {
	Enabled                      bool
	ClientCertificateKeyFile     string
	ClientCertificateKeyPassword func() string
	Insecure                     bool
	CaFile                       string
}

// Credential holds auth options.
//
// AuthMechanism indicates the mechanism to use for authentication.
// Supported values include "SCRAM-SHA-256", "SCRAM-SHA-1", "MONGODB-CR", "PLAIN", "GSSAPI", and "MONGODB-X509".
//
// AuthMechanismProperties specifies additional configuration options which may be used by certain
// authentication mechanisms.
//
// AuthSource specifies the database to authenticate against.
//
// Username specifies the username that will be authenticated.
//
// Password specifies the password used for authentication.
type Credential struct {
	AuthMechanism           string
	AuthMechanismProperties map[string]string
	AuthSource              string
	Username                string
	Password                string
}

// ClientOptions represents all possbile options to configure a client.
type ClientOptions struct {
	TopologyOptions []topology.Option
	ConnString      connstring.ConnString
	RetryWrites     *bool
	ReadPreference  *readpref.ReadPref
	ReadConcern     *readconcern.ReadConcern
	WriteConcern    *writeconcern.WriteConcern
	Registry        *bsoncodec.Registry
}

// Client creates a new ClientOptions instance.
func Client() *ClientOptions {
	return &ClientOptions{
		TopologyOptions: make([]topology.Option, 0),
	}
}

// SetAppName specifies the client application name. This value is used by MongoDB when it logs
// connection information and profile information, such as slow queries.
func (c *ClientOptions) SetAppName(s string) *ClientOptions {
	c.ConnString.AppName = s

	return c
}

// SetAuth sets the authentication options.
func (c *ClientOptions) SetAuth(auth Credential) *ClientOptions {
	c.ConnString.AuthMechanism = auth.AuthMechanism
	c.ConnString.AuthMechanismProperties = auth.AuthMechanismProperties
	c.ConnString.AuthSource = auth.AuthSource
	c.ConnString.Username = auth.Username
	c.ConnString.Password = auth.Password

	return c
}

// SetConnectTimeout specifies the timeout for an initial connection to a server.
// If a custom Dialer is used, this method won't be set and the user is
// responsible for setting the ConnectTimeout for connections on the dialer
// themselves.
func (c *ClientOptions) SetConnectTimeout(d time.Duration) *ClientOptions {
	c.ConnString.ConnectTimeout = d
	c.ConnString.ConnectTimeoutSet = true

	return c
}

// SetDialer specifies a custom dialer used to dial new connections to a server.
// If a custom dialer is not set, a net.Dialer with a 300 second keepalive time will be used by default.
func (c *ClientOptions) SetDialer(d ContextDialer) *ClientOptions {
	c.TopologyOptions = append(
		c.TopologyOptions,
		topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
			return append(
				opts,
				topology.WithConnectionOptions(func(opts ...connection.Option) []connection.Option {
					return append(
						opts,
						connection.WithDialer(func(connection.Dialer) connection.Dialer {
							return d
						}),
					)
				}),
			)
		}),
	)

	return c
}

// SetMonitor specifies a command monitor used to see commands for a client.
func (c *ClientOptions) SetMonitor(m *event.CommandMonitor) *ClientOptions {
	c.TopologyOptions = append(
		c.TopologyOptions,
		topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
			return append(
				opts,
				topology.WithConnectionOptions(func(opts ...connection.Option) []connection.Option {
					return append(
						opts,
						connection.WithMonitor(func(*event.CommandMonitor) *event.CommandMonitor {
							return m
						}),
					)
				}),
			)
		}),
	)

	return c
}

// SetHeartbeatInterval specifies the interval to wait between server monitoring checks.
func (c *ClientOptions) SetHeartbeatInterval(d time.Duration) *ClientOptions {
	c.ConnString.HeartbeatInterval = d
	c.ConnString.HeartbeatIntervalSet = true

	return c
}

// SetHosts specifies the initial list of addresses from which to discover the rest of the cluster.
func (c *ClientOptions) SetHosts(s []string) *ClientOptions {
	c.ConnString.Hosts = s

	return c
}

// SetLocalThreshold specifies how far to distribute queries, beyond the server with the fastest
// round-trip time. If a server's roundtrip time is more than LocalThreshold slower than the
// the fastest, the driver will not send queries to that server.
func (c *ClientOptions) SetLocalThreshold(d time.Duration) *ClientOptions {
	c.ConnString.LocalThreshold = d
	c.ConnString.LocalThresholdSet = true

	return c
}

// SetMaxConnIdleTime specifies the maximum number of milliseconds that a connection can remain idle
// in a connection pool before being removed and closed.
func (c *ClientOptions) SetMaxConnIdleTime(d time.Duration) *ClientOptions {
	c.ConnString.MaxConnIdleTime = d
	c.ConnString.MaxConnIdleTimeSet = true

	return c
}

// SetMaxPoolSize specifies the max size of a server's connection pool.
func (c *ClientOptions) SetMaxPoolSize(u uint16) *ClientOptions {
	c.ConnString.MaxPoolSize = u
	c.ConnString.MaxPoolSizeSet = true

	return c
}

// SetReadConcern specifies the read concern.
func (c *ClientOptions) SetReadConcern(rc *readconcern.ReadConcern) *ClientOptions {
	c.ReadConcern = rc

	return c
}

// SetReadPreference specifies the read preference.
func (c *ClientOptions) SetReadPreference(rp *readpref.ReadPref) *ClientOptions {
	c.ReadPreference = rp

	return c
}

// SetRegistry specifies the bsoncodec.Registry.
func (c *ClientOptions) SetRegistry(registry *bsoncodec.Registry) *ClientOptions {
	c.Registry = registry

	// add registry to the server options so that it will be used for the cursors built by this client
	c.TopologyOptions = append(
		c.TopologyOptions,
		topology.WithServerOptions(func(opts ...topology.ServerOption) []topology.ServerOption {
			return append(
				opts,
				topology.WithRegistry(func(*bsoncodec.Registry) *bsoncodec.Registry {
					return registry
				}),
			)
		}),
	)

	return c
}

// SetReplicaSet specifies the name of the replica set of the cluster.
func (c *ClientOptions) SetReplicaSet(s string) *ClientOptions {
	c.ConnString.ReplicaSet = s

	return c
}

// SetRetryWrites specifies whether the client has retryable writes enabled.
func (c *ClientOptions) SetRetryWrites(b bool) *ClientOptions {
	c.RetryWrites = &b

	return c
}

// SetServerSelectionTimeout specifies a timeout in milliseconds to block for server selection.
func (c *ClientOptions) SetServerSelectionTimeout(d time.Duration) *ClientOptions {
	c.ConnString.ServerSelectionTimeout = d
	c.ConnString.ServerSelectionTimeoutSet = true

	return c
}

// SetSingle specifies whether the driver should connect directly to the server instead of
// auto-discovering other servers in the cluster.
func (c *ClientOptions) SetSingle(b bool) *ClientOptions {
	if b {
		c.ConnString.Connect = connstring.SingleConnect
	} else {
		c.ConnString.Connect = connstring.AutoConnect
	}
	c.ConnString.ConnectSet = true

	return c
}

// SetSocketTimeout specifies the time in milliseconds to attempt to send or receive on a socket
// before the attempt times out.
func (c *ClientOptions) SetSocketTimeout(d time.Duration) *ClientOptions {
	c.ConnString.SocketTimeout = d
	c.ConnString.SocketTimeoutSet = true

	return c
}

// SetSSL sets SSL options.
func (c *ClientOptions) SetSSL(ssl *SSLOpt) *ClientOptions {
	c.ConnString.SSL = ssl.Enabled
	c.ConnString.SSLSet = true

	if ssl.ClientCertificateKeyFile != "" {
		c.ConnString.SSLClientCertificateKeyFile = ssl.ClientCertificateKeyFile
		c.ConnString.SSLClientCertificateKeyFileSet = true
	}

	if ssl.ClientCertificateKeyPassword != nil {
		c.ConnString.SSLClientCertificateKeyPassword = ssl.ClientCertificateKeyPassword
		c.ConnString.SSLClientCertificateKeyPasswordSet = true
	}

	c.ConnString.SSLInsecure = ssl.Insecure
	c.ConnString.SSLInsecureSet = true

	if ssl.CaFile != "" {
		c.ConnString.SSLCaFile = ssl.CaFile
		c.ConnString.SSLCaFileSet = true
	}

	return c
}

// SetWriteConcern sets the write concern.
func (c *ClientOptions) SetWriteConcern(wc *writeconcern.WriteConcern) *ClientOptions {
	c.WriteConcern = wc

	return c
}

// MergeClientOptions combines the given connstring and *ClientOptions into a single *ClientOptions in a last one wins
// fashion. The given connstring will be used for the default options, which can be overwritten using the given
// *ClientOptions.
func MergeClientOptions(cs connstring.ConnString, opts ...*ClientOptions) *ClientOptions {
	c := Client()
	c.ConnString = cs

	for _, opt := range opts {
		if opt == nil {
			continue
		}
		c.TopologyOptions = append(c.TopologyOptions, opt.TopologyOptions...)

		if an := opt.ConnString.AppName; an != "" {
			c.ConnString.AppName = an
		}
		if am := opt.ConnString.AuthMechanism; len(am) != 0 {
			c.ConnString.AuthMechanism = am
		}
		if amp := opt.ConnString.AuthMechanismProperties; amp != nil {
			c.ConnString.AuthMechanismProperties = amp
		}
		if as := opt.ConnString.AuthSource; len(as) != 0 {
			c.ConnString.AuthSource = as
		}
		if u := opt.ConnString.Username; len(u) != 0 {
			c.ConnString.Username = u
		}
		if p := opt.ConnString.Password; len(p) != 0 {
			c.ConnString.Password = p
		}
		if opt.ConnString.ConnectTimeoutSet {
			c.ConnString.ConnectTimeoutSet = true
			c.ConnString.ConnectTimeout = opt.ConnString.ConnectTimeout
		}
		if opt.ConnString.HeartbeatIntervalSet {
			c.ConnString.HeartbeatIntervalSet = true
			c.ConnString.HeartbeatInterval = opt.ConnString.HeartbeatInterval
		}
		if h := opt.ConnString.Hosts; h != nil {
			c.ConnString.Hosts = h
		}
		if opt.ConnString.LocalThresholdSet {
			c.ConnString.LocalThresholdSet = true
			c.ConnString.LocalThreshold = opt.ConnString.LocalThreshold
		}
		if opt.ConnString.MaxConnIdleTimeSet {
			c.ConnString.MaxConnIdleTimeSet = true
			c.ConnString.MaxConnIdleTime = opt.ConnString.MaxConnIdleTime
		}
		if opt.ConnString.MaxPoolSizeSet {
			c.ConnString.MaxPoolSizeSet = true
			c.ConnString.MaxPoolSize = opt.ConnString.MaxPoolSize
		}
		if opt.ReadConcern != nil {
			c.ReadConcern = opt.ReadConcern
		}
		if opt.ReadPreference != nil {
			c.ReadPreference = opt.ReadPreference
		}
		if opt.Registry != nil {
			c.Registry = opt.Registry
		}
		if rs := opt.ConnString.ReplicaSet; rs != "" {
			c.ConnString.ReplicaSet = rs
		}
		if opt.RetryWrites != nil {
			c.RetryWrites = opt.RetryWrites
		}
		if opt.ConnString.ServerSelectionTimeoutSet {
			c.ConnString.ServerSelectionTimeoutSet = true
			c.ConnString.ServerSelectionTimeout = opt.ConnString.ServerSelectionTimeout
		}
		if opt.ConnString.ConnectSet {
			c.ConnString.ConnectSet = true
			c.ConnString.Connect = opt.ConnString.Connect
		}
		if opt.ConnString.SocketTimeoutSet {
			c.ConnString.SocketTimeoutSet = true
			c.ConnString.SocketTimeout = opt.ConnString.SocketTimeout
		}
		if opt.ConnString.SSLSet {
			c.ConnString.SSLSet = true
			c.ConnString.SSL = opt.ConnString.SSL
		}
		if opt.ConnString.SSLClientCertificateKeyFileSet {
			c.ConnString.SSLClientCertificateKeyFileSet = true
			c.ConnString.SSLClientCertificateKeyFile = opt.ConnString.SSLClientCertificateKeyFile
		}
		if opt.ConnString.SSLClientCertificateKeyPasswordSet {
			c.ConnString.SSLClientCertificateKeyPasswordSet = true
			c.ConnString.SSLClientCertificateKeyPassword = opt.ConnString.SSLClientCertificateKeyPassword
		}
		if opt.ConnString.SSLInsecureSet {
			c.ConnString.SSLInsecureSet = true
			c.ConnString.SSLInsecure = opt.ConnString.SSLInsecure
		}
		if opt.ConnString.SSLCaFileSet {
			c.ConnString.SSLCaFileSet = true
			c.ConnString.SSLCaFile = opt.ConnString.SSLCaFile
		}
		if opt.WriteConcern != nil {
			c.WriteConcern = opt.WriteConcern
		}
	}

	return c
}
