// Package zot provides a client for checking zot container registry health.
package zot

import (
	"context"
	"fmt"
	"net/http"
	"time"

	"github.com/orchard9/rdev/internal/domain"
)

// Client checks zot registry health via the OCI /v2/ endpoint.
type Client struct {
	url        string
	httpClient *http.Client
}

// NewClient creates a new zot health checker.
// The URL should be the registry base URL (e.g., "https://registry.threesix.ai").
func NewClient(url string) *Client {
	return &Client{
		url: url,
		httpClient: &http.Client{
			Timeout: 5 * time.Second,
		},
	}
}

// Check returns the health status of the registry.
// A 200 or 401 response indicates the registry is healthy (401 means auth required but registry is up).
func (c *Client) Check(ctx context.Context) domain.RegistryStatus {
	start := time.Now()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.url+"/v2/", nil)
	if err != nil {
		return domain.RegistryStatus{
			Healthy:     false,
			URL:         c.url,
			Error:       fmt.Sprintf("failed to create request: %v", err),
			LastChecked: time.Now().UTC(),
		}
	}

	resp, err := c.httpClient.Do(req)
	latency := time.Since(start)

	if err != nil {
		return domain.RegistryStatus{
			Healthy:     false,
			URL:         c.url,
			Latency:     latency.String(),
			Error:       fmt.Sprintf("connection error: %v", err),
			LastChecked: time.Now().UTC(),
		}
	}
	defer func() { _ = resp.Body.Close() }()

	// 200 = healthy, 401 = healthy but requires auth
	healthy := resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusUnauthorized

	status := domain.RegistryStatus{
		Healthy:     healthy,
		URL:         c.url,
		Latency:     latency.String(),
		LastChecked: time.Now().UTC(),
	}

	if !healthy {
		status.Error = fmt.Sprintf("unexpected status code: %d", resp.StatusCode)
	}

	return status
}
