~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
88 lines · 2.1 KB Raw History
package pdsclient

import (
	"net"
	"net/http"

	"context"
	"fmt"
	"strings"
	"time"

	"github.com/johnandersen777/socialweb-computer-kcp/internal/atproto/xrpc"

	"github.com/johnandersen777/socialweb-computer-kcp/internal/kit/kcp"
)

type LocalRef struct {
	Workspace string
	Kind      string
	Name      string
	Endpoint  string
}

type Handlers interface {
	HTTPClient() *http.Client

	DialHTTP(ctx context.Context, address string) (net.Conn, error)
}

type LocalConfig struct {
	Handlers Handlers
	BaseURL  string
	Tokens   TokenSource
	DPoP     DPoPSource
	Auth     xrpc.Auth
	Timeout  time.Duration
}

type LocalPDS struct {
	*basePDS
}

var _ PDS = (*LocalPDS)(nil)
var _ Ref = LocalRef{}

func NewLocal(cfg LocalConfig) (*LocalPDS, error) {
	if cfg.Handlers == nil {
		return nil, fmt.Errorf("%w: local handler registry is required", ErrInvalidConfig)
	}
	baseURL, err := parseBaseURL(cfg.BaseURL, "http")
	if err != nil {
		return nil, err
	}
	httpClient := cloneNoRedirect(cfg.Handlers.HTTPClient())
	client := newXRPCClient(baseURL, httpClient, cfg.Tokens, cfg.DPoP, cfg.Auth, cfg.Timeout)
	handlers := cfg.Handlers
	dial := func(ctx context.Context, cursor *int64) (RepoEventStream, error) {
		return newLocalSubscribe(ctx, handlers, baseURL, cursor)
	}
	return &LocalPDS{basePDS: &basePDS{client: client, dial: dial}}, nil
}

func (r LocalRef) baseURL() (string, error) {
	endpoint := strings.TrimSpace(r.Endpoint)
	if endpoint != "" {
		if !strings.Contains(endpoint, "://") {
			endpoint = "http://" + endpoint
		}
		parsed, err := parseBaseURL(endpoint, "http")
		if err != nil {
			return "", err
		}
		return parsed.String(), nil
	}
	kind := strings.ToLower(strings.TrimSpace(r.Kind))
	if kind == "" {
		return "", fmt.Errorf("%w: local kind is required", ErrInvalidConfig)
	}
	name := strings.ToLower(strings.TrimSpace(r.Name))
	if name != "" {
		return "http://" + kind + "." + name, nil
	}
	workspace := strings.TrimSpace(r.Workspace)
	if workspace != "" {
		return "http://" + kcp.ServiceFQDN(kind, "default", workspace, kcp.DefaultServiceDomain), nil
	}
	return "", fmt.Errorf("%w: local name or workspace is required", ErrInvalidConfig)
}