// Package config provides configuration validation and management.
package config

import (
	"fmt"
	"net"
	"os"
)

// Validator is an interface for types that can validate themselves.
type Validator interface {
	Validate() error
}

// ValidateConfig validates a configuration struct that implements the Validator interface.
func ValidateConfig(v Validator) error {
	return v.Validate()
}

// ValidatePort checks if a port number is within the valid range (1-65535).
func ValidatePort(port int) error {
	if port < 1 || port > 65535 {
		return fmt.Errorf("invalid port: %d (must be 1-65535)", port)
	}
	return nil
}

// ValidateDirectory checks if a path exists and is a directory.
func ValidateDirectory(path string) error {
	if path == "" {
		return fmt.Errorf("path cannot be empty")
	}

	expanded := ExpandPath(path)
	info, err := os.Stat(expanded)
	if err != nil {
		if os.IsNotExist(err) {
			return fmt.Errorf("directory does not exist: %s", expanded)
		}
		return fmt.Errorf("cannot access directory %s: %w", expanded, err)
	}

	if !info.IsDir() {
		return fmt.Errorf("path is not a directory: %s", expanded)
	}

	return nil
}

// ValidateRedisAddr validates a Redis address in the format "host:port".
func ValidateRedisAddr(addr string) error {
	host, port, err := net.SplitHostPort(addr)
	if err != nil {
		return fmt.Errorf("invalid redis address format: %w", err)
	}

	if host == "" {
		return fmt.Errorf("redis host cannot be empty")
	}

	var portInt int
	if _, err := fmt.Sscanf(port, "%d", &portInt); err != nil {
		return fmt.Errorf("invalid port number %q: %w", port, err)
	}

	return ValidatePort(portInt)
}
