// ABOUTME: Core EdgeXR Master Controller SDK client with HTTP transport and auth
// ABOUTME: Provides typed APIs for app, instance, and cloudlet management operations

package v2

import (
	"net/http"
	"strings"
	"time"
)

// Client represents the EdgeXR Master Controller SDK client
type Client struct {
	BaseURL      string
	HTTPClient   *http.Client
	AuthProvider AuthProvider
	RetryOpts    RetryOptions
	Logger       Logger
}

// RetryOptions configures retry behavior for API calls
type RetryOptions struct {
	MaxRetries               int
	InitialDelay             time.Duration
	MaxDelay                 time.Duration
	Multiplier               float64
	RetryableHTTPStatusCodes []int
}

// Logger interface for optional logging
type Logger interface {
	Printf(format string, v ...interface{})
}

// DefaultRetryOptions returns sensible default retry configuration
func DefaultRetryOptions() RetryOptions {
	return RetryOptions{
		MaxRetries:   3,
		InitialDelay: 1 * time.Second,
		MaxDelay:     30 * time.Second,
		Multiplier:   2.0,
		RetryableHTTPStatusCodes: []int{
			http.StatusRequestTimeout,
			http.StatusTooManyRequests,
			http.StatusInternalServerError,
			http.StatusBadGateway,
			http.StatusServiceUnavailable,
			http.StatusGatewayTimeout,
		},
	}
}

// Option represents a configuration option for the client
type Option func(*Client)

// WithHTTPClient sets a custom HTTP client
func WithHTTPClient(client *http.Client) Option {
	return func(c *Client) {
		c.HTTPClient = client
	}
}

// WithAuthProvider sets the authentication provider
func WithAuthProvider(auth AuthProvider) Option {
	return func(c *Client) {
		c.AuthProvider = auth
	}
}

// WithRetryOptions sets retry configuration
func WithRetryOptions(opts RetryOptions) Option {
	return func(c *Client) {
		c.RetryOpts = opts
	}
}

// WithLogger sets a logger for debugging
func WithLogger(logger Logger) Option {
	return func(c *Client) {
		c.Logger = logger
	}
}

// NewClient creates a new EdgeXR SDK client
func NewClient(baseURL string, options ...Option) *Client {
	client := &Client{
		BaseURL:      strings.TrimRight(baseURL, "/"),
		HTTPClient:   &http.Client{Timeout: 30 * time.Second},
		AuthProvider: NewNoAuthProvider(),
		RetryOpts:    DefaultRetryOptions(),
	}

	for _, opt := range options {
		opt(client)
	}

	return client
}

// NewClientWithCredentials creates a new EdgeXR SDK client with username/password authentication
// This matches the existing client pattern from client/client.go
func NewClientWithCredentials(baseURL, username, password string, options ...Option) *Client {
	client := &Client{
		BaseURL:      strings.TrimRight(baseURL, "/"),
		HTTPClient:   &http.Client{Timeout: 30 * time.Second},
		AuthProvider: NewUsernamePasswordProvider(baseURL, username, password, nil),
		RetryOpts:    DefaultRetryOptions(),
	}

	for _, opt := range options {
		opt(client)
	}

	return client
}

// logf logs a message if a logger is configured
func (c *Client) logf(format string, v ...interface{}) {
	if c.Logger != nil {
		c.Logger.Printf(format, v...)
	}
}
