~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
84 lines · 2.3 KB Raw History
package remote

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

	"github.com/bluesky-social/indigo/atproto/identity"
	"github.com/bluesky-social/indigo/atproto/syntax"

	commonv1 "github.com/johnandersen777/socialweb-computer-kcp/api/common/v1alpha1"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/atproto/pdsclient"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/contract/atprotorepo"
)

type NetworkConfig struct {
	Directory identity.Directory

	HTTP *http.Client
}

type Network struct {
	directory identity.Directory

	http *http.Client
}

var _ atprotorepo.RecordReader = (*Network)(nil)

func NewNetwork(cfg NetworkConfig) *Network {
	return &Network{directory: cfg.Directory, http: cfg.HTTP}
}

func (n *Network) repo(ctx context.Context, raw string) (*Repo, error) {
	if n.directory == nil {
		return nil, errors.New("remote: the network reader has no identity directory")
	}
	did, err := syntax.ParseDID(raw)
	if err != nil {
		return nil, fmt.Errorf("remote: %q is not a DID: %w", raw, err)
	}
	ident, err := n.directory.LookupDID(ctx, did)
	if err != nil {
		return nil, fmt.Errorf("remote: resolving %s: %w", did, err)
	}
	endpoint := ident.PDSEndpoint()
	if endpoint == "" {
		return nil, fmt.Errorf("remote: the DID document of %s names no PDS", did)
	}
	client, err := pdsclient.NewRemote(pdsclient.RemoteConfig{BaseURL: endpoint, HTTPClient: n.http, Timeout: DefaultTimeout})
	if err != nil {
		return nil, err
	}
	return Wrap(client, did), nil
}

func (n *Network) GetRecord(ctx context.Context, repo, collection, rkey string) (atprotorepo.Record, error) {
	r, err := n.repo(ctx, repo)
	if err != nil {
		return atprotorepo.Record{}, err
	}
	return r.GetRecord(ctx, repo, collection, rkey)
}

func (n *Network) ListRecords(ctx context.Context, repo, collection string, opts atprotorepo.ListOptions) (atprotorepo.ListPage, error) {
	r, err := n.repo(ctx, repo)
	if err != nil {
		return atprotorepo.ListPage{}, err
	}
	return r.ListRecords(ctx, repo, collection, opts)
}

func (n *Network) Resolve(ctx context.Context, ref commonv1.StrongRef) (atprotorepo.Record, error) {
	uri, err := syntax.ParseATURI(ref.URI)
	if err != nil {
		return atprotorepo.Record{}, fmt.Errorf("remote: the record uri %q: %w", ref.URI, err)
	}
	r, err := n.repo(ctx, uri.Authority().String())
	if err != nil {
		return atprotorepo.Record{}, err
	}
	return r.Resolve(ctx, ref)
}