// Code generated by Fern. DO NOT EDIT.

package client

import (
	context "context"
	fmt "fmt"
	management "github.com/auth0/go-auth0/v2/management"
	connections "github.com/auth0/go-auth0/v2/management/clients/connections"
	credentials "github.com/auth0/go-auth0/v2/management/clients/credentials"
	core "github.com/auth0/go-auth0/v2/management/core"
	internal "github.com/auth0/go-auth0/v2/management/internal"
	option "github.com/auth0/go-auth0/v2/management/option"
	http "net/http"
	strconv "strconv"
)

type Client struct {
	WithRawResponse *RawClient
	Credentials     *credentials.Client
	Connections     *connections.Client

	options *core.RequestOptions
	baseURL string
	caller  *internal.Caller
}

func NewClient(options *core.RequestOptions) *Client {
	return &Client{
		Credentials:     credentials.NewClient(options),
		Connections:     connections.NewClient(options),
		WithRawResponse: NewRawClient(options),
		options:         options,
		baseURL:         options.BaseURL,
		caller: internal.NewCaller(
			&internal.CallerParams{
				Client:      options.HTTPClient,
				MaxAttempts: options.MaxAttempts,
			},
		),
	}
}

// Retrieve clients (applications and SSO integrations) matching provided filters. A list of fields to include or exclude may also be specified.
// For more information, read <a href="https://www.auth0.com/docs/get-started/applications"> Applications in Auth0</a> and <a href="https://www.auth0.com/docs/authenticate/single-sign-on"> Single Sign-On</a>.
//
// <ul>
//
//	<li>
//	  The following can be retrieved with any scope:
//	  <code>client_id</code>, <code>app_type</code>, <code>name</code>, and <code>description</code>.
//	</li>
//	<li>
//	  The following properties can only be retrieved with the <code>read:clients</code> or
//	  <code>read:client_keys</code> scope:
//	  <code>callbacks</code>, <code>oidc_logout</code>, <code>allowed_origins</code>,
//	  <code>web_origins</code>, <code>tenant</code>, <code>global</code>, <code>config_route</code>,
//	  <code>callback_url_template</code>, <code>jwt_configuration</code>,
//	  <code>jwt_configuration.lifetime_in_seconds</code>, <code>jwt_configuration.secret_encoded</code>,
//	  <code>jwt_configuration.scopes</code>, <code>jwt_configuration.alg</code>, <code>api_type</code>,
//	  <code>logo_uri</code>, <code>allowed_clients</code>, <code>owners</code>, <code>custom_login_page</code>,
//	  <code>custom_login_page_off</code>, <code>sso</code>, <code>addons</code>, <code>form_template</code>,
//	  <code>custom_login_page_codeview</code>, <code>resource_servers</code>, <code>client_metadata</code>,
//	  <code>mobile</code>, <code>mobile.android</code>, <code>mobile.ios</code>, <code>allowed_logout_urls</code>,
//	  <code>token_endpoint_auth_method</code>, <code>is_first_party</code>, <code>oidc_conformant</code>,
//	  <code>is_token_endpoint_ip_header_trusted</code>, <code>initiate_login_uri</code>, <code>grant_types</code>,
//	  <code>refresh_token</code>, <code>refresh_token.rotation_type</code>, <code>refresh_token.expiration_type</code>,
//	  <code>refresh_token.leeway</code>, <code>refresh_token.token_lifetime</code>, <code>refresh_token.policies</code>, <code>organization_usage</code>,
//	  <code>organization_require_behavior</code>.
//	</li>
//	<li>
//	  The following properties can only be retrieved with the
//	  <code>read:client_keys</code> or <code>read:client_credentials</code> scope:
//	  <code>encryption_key</code>, <code>encryption_key.pub</code>, <code>encryption_key.cert</code>,
//	  <code>client_secret</code>, <code>client_authentication_methods</code> and <code>signing_key</code>.
//	</li>
//
// </ul>
func (c *Client) List(
	ctx context.Context,
	request *management.ListClientsRequestParameters,
	opts ...option.RequestOption,
) (*core.Page[*management.Client], error) {
	options := core.NewRequestOptions(opts...)
	baseURL := internal.ResolveBaseURL(
		options.BaseURL,
		c.baseURL,
		"https://%7BTENANT%7D.auth0.com/api/v2",
	)
	endpointURL := baseURL + "/clients"
	queryParams, err := internal.QueryValues(request)
	if err != nil {
		return nil, err
	}
	headers := internal.MergeHeaders(
		c.options.ToHeader(),
		options.ToHeader(),
	)
	prepareCall := func(pageRequest *internal.PageRequest[*int]) *internal.CallParams {
		if pageRequest.Cursor != nil {
			queryParams.Set("page", fmt.Sprintf("%v", *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(management.ErrorCodes),
		}
	}
	next := 1
	if queryParams.Has("page") {
		var err error
		if next, err = strconv.Atoi(queryParams.Get("page")); err != nil {
			return nil, err
		}
	}

	readPageResponse := func(response *management.ListClientsOffsetPaginatedResponseContent) *internal.PageResponse[*int, *management.Client] {
		next += 1
		results := response.Clients
		return &internal.PageResponse[*int, *management.Client]{
			Next:    &next,
			Results: results,
		}
	}
	pager := internal.NewOffsetPager(
		c.caller,
		prepareCall,
		readPageResponse,
	)
	return pager.GetPage(ctx, &next)
}

// Create a new client (application or SSO integration). For more information, read <a href="https://www.auth0.com/docs/get-started/auth0-overview/create-applications">Create Applications</a>
// <a href="https://www.auth0.com/docs/authenticate/single-sign-on/api-endpoints-for-single-sign-on>">API Endpoints for Single Sign-On</a>.
//
// Notes:
// - We recommend leaving the `client_secret` parameter unspecified to allow the generation of a safe secret.
// - The <code>client_authentication_methods</code> and <code>token_endpoint_auth_method</code> properties are mutually exclusive. Use
// <code>client_authentication_methods</code> to configure the client with Private Key JWT authentication method. Otherwise, use <code>token_endpoint_auth_method</code>
// to configure the client with client secret (basic or post) or with no authentication method (none).
// - When using <code>client_authentication_methods</code> to configure the client with Private Key JWT authentication method, specify fully defined credentials.
// These credentials will be automatically enabled for Private Key JWT authentication on the client.
// - To configure <code>client_authentication_methods</code>, the <code>create:client_credentials</code> scope is required.
// - To configure <code>client_authentication_methods</code>, the property <code>jwt_configuration.alg</code> must be set to RS256.
//
// <div class="alert alert-warning">SSO Integrations created via this endpoint will accept login requests and share user profile information.</div>
func (c *Client) Create(
	ctx context.Context,
	request *management.CreateClientRequestContent,
	opts ...option.RequestOption,
) (*management.CreateClientResponseContent, error) {
	response, err := c.WithRawResponse.Create(
		ctx,
		request,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}

// Retrieve client details by ID. Clients are SSO connections or Applications linked with your Auth0 tenant. A list of fields to include or exclude may also be specified.
// For more information, read <a href="https://www.auth0.com/docs/get-started/applications"> Applications in Auth0</a> and <a href="https://www.auth0.com/docs/authenticate/single-sign-on"> Single Sign-On</a>.
// <ul>
//
//	<li>
//	  The following properties can be retrieved with any of the scopes:
//	  <code>client_id</code>, <code>app_type</code>, <code>name</code>, and <code>description</code>.
//	</li>
//	<li>
//	  The following properties can only be retrieved with the <code>read:clients</code> or
//	  <code>read:client_keys</code> scopes:
//	  <code>callbacks</code>, <code>oidc_logout</code>, <code>allowed_origins</code>,
//	  <code>web_origins</code>, <code>tenant</code>, <code>global</code>, <code>config_route</code>,
//	  <code>callback_url_template</code>, <code>jwt_configuration</code>,
//	  <code>jwt_configuration.lifetime_in_seconds</code>, <code>jwt_configuration.secret_encoded</code>,
//	  <code>jwt_configuration.scopes</code>, <code>jwt_configuration.alg</code>, <code>api_type</code>,
//	  <code>logo_uri</code>, <code>allowed_clients</code>, <code>owners</code>, <code>custom_login_page</code>,
//	  <code>custom_login_page_off</code>, <code>sso</code>, <code>addons</code>, <code>form_template</code>,
//	  <code>custom_login_page_codeview</code>, <code>resource_servers</code>, <code>client_metadata</code>,
//	  <code>mobile</code>, <code>mobile.android</code>, <code>mobile.ios</code>, <code>allowed_logout_urls</code>,
//	  <code>token_endpoint_auth_method</code>, <code>is_first_party</code>, <code>oidc_conformant</code>,
//	  <code>is_token_endpoint_ip_header_trusted</code>, <code>initiate_login_uri</code>, <code>grant_types</code>,
//	  <code>refresh_token</code>, <code>refresh_token.rotation_type</code>, <code>refresh_token.expiration_type</code>,
//	  <code>refresh_token.leeway</code>, <code>refresh_token.token_lifetime</code>, <code>refresh_token.policies</code>, <code>organization_usage</code>,
//	  <code>organization_require_behavior</code>.
//	</li>
//	<li>
//	  The following properties can only be retrieved with the <code>read:client_keys</code> or <code>read:client_credentials</code> scopes:
//	  <code>encryption_key</code>, <code>encryption_key.pub</code>, <code>encryption_key.cert</code>,
//	  <code>client_secret</code>, <code>client_authentication_methods</code> and <code>signing_key</code>.
//	</li>
//
// </ul>
func (c *Client) Get(
	ctx context.Context,
	// ID of the client to retrieve.
	id string,
	request *management.GetClientRequestParameters,
	opts ...option.RequestOption,
) (*management.GetClientResponseContent, error) {
	response, err := c.WithRawResponse.Get(
		ctx,
		id,
		request,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}

// Delete a client and related configuration (rules, connections, etc).
func (c *Client) Delete(
	ctx context.Context,
	// ID of the client to delete.
	id string,
	opts ...option.RequestOption,
) error {
	_, err := c.WithRawResponse.Delete(
		ctx,
		id,
		opts...,
	)
	if err != nil {
		return err
	}
	return nil
}

// Updates a client's settings. For more information, read <a href="https://www.auth0.com/docs/get-started/applications"> Applications in Auth0</a> and <a href="https://www.auth0.com/docs/authenticate/single-sign-on"> Single Sign-On</a>.
//
// Notes:
// - The `client_secret` and `signing_key` attributes can only be updated with the `update:client_keys` scope.
// - The <code>client_authentication_methods</code> and <code>token_endpoint_auth_method</code> properties are mutually exclusive. Use <code>client_authentication_methods</code> to configure the client with Private Key JWT authentication method. Otherwise, use <code>token_endpoint_auth_method</code> to configure the client with client secret (basic or post) or with no authentication method (none).
// - When using <code>client_authentication_methods</code> to configure the client with Private Key JWT authentication method, only specify the credential IDs that were generated when creating the credentials on the client.
// - To configure <code>client_authentication_methods</code>, the <code>update:client_credentials</code> scope is required.
// - To configure <code>client_authentication_methods</code>, the property <code>jwt_configuration.alg</code> must be set to RS256.
// - To change a client's <code>is_first_party</code> property to <code>false</code>, the <code>organization_usage</code> and <code>organization_require_behavior</code> properties must be unset.
func (c *Client) Update(
	ctx context.Context,
	// ID of the client to update.
	id string,
	request *management.UpdateClientRequestContent,
	opts ...option.RequestOption,
) (*management.UpdateClientResponseContent, error) {
	response, err := c.WithRawResponse.Update(
		ctx,
		id,
		request,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}

// Rotate a client secret.
//
// This endpoint cannot be used with clients configured with Private Key JWT authentication method (client_authentication_methods configured with private_key_jwt). The generated secret is NOT base64 encoded.
//
// For more information, read <a href="https://www.auth0.com/docs/get-started/applications/rotate-client-secret">Rotate Client Secrets</a>.
func (c *Client) RotateSecret(
	ctx context.Context,
	// ID of the client that will rotate secrets.
	id string,
	opts ...option.RequestOption,
) (*management.RotateClientSecretResponseContent, error) {
	response, err := c.WithRawResponse.RotateSecret(
		ctx,
		id,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}
