package mongo

import (
	"fmt"
	"net"
	"net/url"
)

func buildConnectionURI(c Conf) (string, error) {
	scheme := c.Schema
	if scheme == "" {
		scheme = "mongodb"
	}
	host := c.Host
	if host == "" {
		return "", fmt.Errorf("mongo: host is required")
	}
	if c.Port > 0 && !hostHasPort(host) {
		host = fmt.Sprintf("%s:%d", host, c.Port)
	}

	u := &url.URL{
		Scheme: scheme,
		Host:   host,
	}
	if c.User != "" {
		u.User = url.UserPassword(c.User, c.Password)
	}

	q := url.Values{}
	if c.AuthSource != "" {
		q.Set("authSource", c.AuthSource)
	}
	if c.ReplicaName != "" {
		q.Set("replicaSet", c.ReplicaName)
	}
	if c.TLS {
		q.Set("tls", "true")
	}
	if len(q) > 0 {
		u.RawQuery = q.Encode()
	}

	return u.String(), nil
}

func hostHasPort(host string) bool {
	// IPv6 [::1]:27017 or hostname:27017
	if h, _, err := net.SplitHostPort(host); err == nil && h != "" {
		return true
	}
	return false
}

func redactConnectionURI(uri string) string {
	u, err := url.Parse(uri)
	if err != nil || u.User == nil {
		return uri
	}
	if _, hasPassword := u.User.Password(); !hasPassword {
		return uri
	}
	u.User = url.UserPassword(u.User.Username(), "*****")
	return u.String()
}

func defaultCompressors(c Conf) []string {
	if len(c.Compressors) > 0 {
		return c.Compressors
	}
	return []string{"zstd", "snappy"}
}
