// Code generated by Fern. DO NOT EDIT.

package objects

import (
	context "context"
	v2 "github.com/anduril/lattice-sdk-go/v2"
	core "github.com/anduril/lattice-sdk-go/v2/core"
	internal "github.com/anduril/lattice-sdk-go/v2/internal"
	option "github.com/anduril/lattice-sdk-go/v2/option"
	io "io"
	http "net/http"
)

type Client struct {
	WithRawResponse *RawClient

	baseURL string
	caller  *internal.Caller
	header  http.Header
}

func NewClient(opts ...option.RequestOption) *Client {
	options := core.NewRequestOptions(opts...)
	return &Client{
		WithRawResponse: NewRawClient(options),
		baseURL:         options.BaseURL,
		caller: internal.NewCaller(
			&internal.CallerParams{
				Client:      options.HTTPClient,
				MaxAttempts: options.MaxAttempts,
			},
		),
		header: options.ToHeader(),
	}
}

// Lists objects in your environment. You can define a prefix to list a subset of your objects. If you do not set a prefix, Lattice returns all available objects. By default this endpoint will list local objects only.
func (c *Client) ListObjects(
	ctx context.Context,
	request *v2.ListObjectsRequest,
	opts ...option.RequestOption,
) (*core.Page[*v2.PathMetadata], error) {
	options := core.NewRequestOptions(opts...)
	baseURL := internal.ResolveBaseURL(
		options.BaseURL,
		c.baseURL,
		"https://example.developer.anduril.com",
	)
	endpointURL := baseURL + "/api/v1/objects"
	queryParams, err := internal.QueryValues(request)
	if err != nil {
		return nil, err
	}
	headers := internal.MergeHeaders(
		c.header.Clone(),
		options.ToHeader(),
	)
	errorCodes := internal.ErrorCodes{
		400: func(apiError *core.APIError) error {
			return &v2.BadRequestError{
				APIError: apiError,
			}
		},
		401: func(apiError *core.APIError) error {
			return &v2.UnauthorizedError{
				APIError: apiError,
			}
		},
		500: func(apiError *core.APIError) error {
			return &v2.InternalServerError{
				APIError: apiError,
			}
		},
	}
	prepareCall := func(pageRequest *internal.PageRequest[*string]) *internal.CallParams {
		if pageRequest.Cursor != nil {
			queryParams.Set("pageToken", *pageRequest.Cursor)
		}
		nextURL := endpointURL
		if len(queryParams) > 0 {
			nextURL += "?" + queryParams.Encode()
		}
		return &internal.CallParams{
			URL:             nextURL,
			Method:          http.MethodGet,
			Headers:         headers,
			MaxAttempts:     options.MaxAttempts,
			BodyProperties:  options.BodyProperties,
			QueryParameters: options.QueryParameters,
			Client:          options.HTTPClient,
			Response:        pageRequest.Response,
			ErrorDecoder:    internal.NewErrorDecoder(errorCodes),
		}
	}
	readPageResponse := func(response *v2.ListResponse) *internal.PageResponse[*string, *v2.PathMetadata] {
		var zeroValue *string
		next := response.GetNextPageToken()
		results := response.GetPathMetadatas()
		return &internal.PageResponse[*string, *v2.PathMetadata]{
			Next:    next,
			Results: results,
			Done:    next == zeroValue,
		}
	}
	pager := internal.NewCursorPager(
		c.caller,
		prepareCall,
		readPageResponse,
	)
	return pager.GetPage(ctx, request.PageToken)
}

// Fetches an object from your environment using the objectPath path parameter.
func (c *Client) GetObject(
	ctx context.Context,
	// The path of the object to fetch.
	objectPath string,
	request *v2.GetObjectRequest,
	opts ...option.RequestOption,
) (io.Reader, error) {
	response, err := c.WithRawResponse.GetObject(
		ctx,
		objectPath,
		request,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}

// Uploads an object. The object must be 1 GiB or smaller.
func (c *Client) UploadObject(
	ctx context.Context,
	// Path of the Object that is to be uploaded.
	objectPath string,
	request io.Reader,
	opts ...option.RequestOption,
) (*v2.PathMetadata, error) {
	response, err := c.WithRawResponse.UploadObject(
		ctx,
		objectPath,
		request,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}

// Deletes an object from your environment given the objectPath path parameter.
func (c *Client) DeleteObject(
	ctx context.Context,
	// The path of the object to delete.
	objectPath string,
	opts ...option.RequestOption,
) error {
	_, err := c.WithRawResponse.DeleteObject(
		ctx,
		objectPath,
		opts...,
	)
	if err != nil {
		return err
	}
	return nil
}

// Returns metadata for a specified object path. Use this to fetch metadata such as object size (size_bytes), its expiry time (expiry_time), or its latest update timestamp (last_updated_at).
func (c *Client) GetObjectMetadata(
	ctx context.Context,
	// The path of the object to query.
	objectPath string,
	opts ...option.RequestOption,
) error {
	_, err := c.WithRawResponse.GetObjectMetadata(
		ctx,
		objectPath,
		opts...,
	)
	if err != nil {
		return err
	}
	return nil
}
