1// Package client provides a client for interacting with the fur service.
 2package client
 3
 4import (
 5	"encoding/json"
 6	"fmt"
 7	"net/http"
 8	"os"
 9
10	"github.com/charmbracelet/crush/internal/fur/provider"
11)
12
13const defaultURL = "https://fur.charm.sh"
14
15// Client represents a client for the fur service.
16type Client struct {
17	baseURL    string
18	httpClient *http.Client
19}
20
21// New creates a new client instance
22// Uses FUR_URL environment variable or falls back to localhost:8080.
23func New() *Client {
24	baseURL := os.Getenv("FUR_URL")
25	if baseURL == "" {
26		baseURL = defaultURL
27	}
28
29	return &Client{
30		baseURL:    baseURL,
31		httpClient: &http.Client{},
32	}
33}
34
35// NewWithURL creates a new client with a specific URL.
36func NewWithURL(url string) *Client {
37	return &Client{
38		baseURL:    url,
39		httpClient: &http.Client{},
40	}
41}
42
43// GetProviders retrieves all available providers from the service.
44func (c *Client) GetProviders() ([]provider.Provider, error) {
45	url := fmt.Sprintf("%s/providers", c.baseURL)
46
47	resp, err := c.httpClient.Get(url) //nolint:noctx
48	if err != nil {
49		return nil, fmt.Errorf("failed to make request: %w", err)
50	}
51	defer resp.Body.Close() //nolint:errcheck
52
53	if resp.StatusCode != http.StatusOK {
54		return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
55	}
56
57	var providers []provider.Provider
58	if err := json.NewDecoder(resp.Body).Decode(&providers); err != nil {
59		return nil, fmt.Errorf("failed to decode response: %w", err)
60	}
61
62	return providers, nil
63}