/*
1Backend

AI-native microservices platform.

API version: 0.8.2
Contact: sales@singulatron.com
*/

// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.

package openapi

import (
	"bytes"
	"context"
	"io"
	"net/http"
	"net/url"
)


type ConfigSvcAPI interface {

	/*
	ListConfigs List Configs

	Retrieves the current configurations for a specified app.
Since any user can save configurations, it is strongly advised that you supply a list of
owners to filter on.
If no app is specified, the default "unnamed" app is used.
This is a public endpoint and does not require authentication.
Configuration data is non-sensitive. For sensitive data, refer to the Secret Service.

Configurations are used to control frontend behavior, A/B testing, feature flags, and other non-sensitive settings.

	@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
	@return ApiListConfigsRequest
	*/
	ListConfigs(ctx context.Context) ApiListConfigsRequest

	// ListConfigsExecute executes the request
	//  @return ConfigSvcListConfigsResponse
	ListConfigsExecute(r ApiListConfigsRequest) (*ConfigSvcListConfigsResponse, *http.Response, error)

	/*
	SaveConfig Save Config

	Save the provided configuration to the server.
The app from the caller's token is used to determine which app the config belongs to.
The caller's camelCased slug (e.g., "test-user-slug" becomes "testUserSlug") is used as the config key automatically,
except for users who have the "config-svc:config:edit-on-behalf" permission (admins), who can specify any key they want.
Admins (users with the "config-svc:config:edit-on-behalf" permission) can also provide an "app" field in the request body to specify which app the config belongs to, while
non-admin users cannot specify the "app" field, the app associated with their token will be used.

The save performs a deep merge, that is:
- Nested objects are recursively merged rather than replaced.
- If a field exists in both the existing and the incoming config and both values are objects, their contents are merged.
- If a field exists in both but one or both values are not objects (e.g., string, number, array), the incoming value replaces the existing one.
- Fields present only in the incoming config are added.
- Fields present only in the existing config are preserved.
- Top-level and nested merges follow the same rules.

	@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
	@return ApiSaveConfigRequest
	*/
	SaveConfig(ctx context.Context) ApiSaveConfigRequest

	// SaveConfigExecute executes the request
	//  @return map[string]interface{}
	SaveConfigExecute(r ApiSaveConfigRequest) (map[string]interface{}, *http.Response, error)
}

// ConfigSvcAPIService ConfigSvcAPI service
type ConfigSvcAPIService service

type ApiListConfigsRequest struct {
	ctx context.Context
	ApiService ConfigSvcAPI
	body *ConfigSvcListConfigsRequest
}

// List Configs Request
func (r ApiListConfigsRequest) Body(body ConfigSvcListConfigsRequest) ApiListConfigsRequest {
	r.body = &body
	return r
}

func (r ApiListConfigsRequest) Execute() (*ConfigSvcListConfigsResponse, *http.Response, error) {
	return r.ApiService.ListConfigsExecute(r)
}

/*
ListConfigs List Configs

Retrieves the current configurations for a specified app.
Since any user can save configurations, it is strongly advised that you supply a list of
owners to filter on.
If no app is specified, the default "unnamed" app is used.
This is a public endpoint and does not require authentication.
Configuration data is non-sensitive. For sensitive data, refer to the Secret Service.

Configurations are used to control frontend behavior, A/B testing, feature flags, and other non-sensitive settings.

 @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
 @return ApiListConfigsRequest
*/
func (a *ConfigSvcAPIService) ListConfigs(ctx context.Context) ApiListConfigsRequest {
	return ApiListConfigsRequest{
		ApiService: a,
		ctx: ctx,
	}
}

// Execute executes the request
//  @return ConfigSvcListConfigsResponse
func (a *ConfigSvcAPIService) ListConfigsExecute(r ApiListConfigsRequest) (*ConfigSvcListConfigsResponse, *http.Response, error) {
	var (
		localVarHTTPMethod   = http.MethodPost
		localVarPostBody     interface{}
		formFiles            []formFile
		localVarReturnValue  *ConfigSvcListConfigsResponse
	)

	localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ConfigSvcAPIService.ListConfigs")
	if err != nil {
		return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
	}

	localVarPath := localBasePath + "/config-svc/configs"

	localVarHeaderParams := make(map[string]string)
	localVarQueryParams := url.Values{}
	localVarFormParams := url.Values{}
	if r.body == nil {
		return localVarReturnValue, nil, reportError("body is required and must be specified")
	}

	// to determine the Content-Type header
	localVarHTTPContentTypes := []string{"application/json"}

	// set Content-Type header
	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
	if localVarHTTPContentType != "" {
		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
	}

	// to determine the Accept header
	localVarHTTPHeaderAccepts := []string{"application/json"}

	// set Accept header
	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
	if localVarHTTPHeaderAccept != "" {
		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
	}
	// body params
	localVarPostBody = r.body
	req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
	if err != nil {
		return localVarReturnValue, nil, err
	}

	localVarHTTPResponse, err := a.client.callAPI(req)
	if err != nil || localVarHTTPResponse == nil {
		return localVarReturnValue, localVarHTTPResponse, err
	}

	localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
	localVarHTTPResponse.Body.Close()
	localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
	if err != nil {
		return localVarReturnValue, localVarHTTPResponse, err
	}

	if localVarHTTPResponse.StatusCode >= 300 {
		newErr := &GenericOpenAPIError{
			body:  localVarBody,
			error: localVarHTTPResponse.Status,
		}
		if localVarHTTPResponse.StatusCode == 401 {
			var v string
			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
			if err != nil {
				newErr.error = err.Error()
				return localVarReturnValue, localVarHTTPResponse, newErr
			}
					newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
					newErr.model = v
			return localVarReturnValue, localVarHTTPResponse, newErr
		}
		if localVarHTTPResponse.StatusCode == 500 {
			var v string
			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
			if err != nil {
				newErr.error = err.Error()
				return localVarReturnValue, localVarHTTPResponse, newErr
			}
					newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
					newErr.model = v
		}
		return localVarReturnValue, localVarHTTPResponse, newErr
	}

	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
	if err != nil {
		newErr := &GenericOpenAPIError{
			body:  localVarBody,
			error: err.Error(),
		}
		return localVarReturnValue, localVarHTTPResponse, newErr
	}

	return localVarReturnValue, localVarHTTPResponse, nil
}

type ApiSaveConfigRequest struct {
	ctx context.Context
	ApiService ConfigSvcAPI
	body *ConfigSvcSaveConfigRequest
}

// Save Config Request
func (r ApiSaveConfigRequest) Body(body ConfigSvcSaveConfigRequest) ApiSaveConfigRequest {
	r.body = &body
	return r
}

func (r ApiSaveConfigRequest) Execute() (map[string]interface{}, *http.Response, error) {
	return r.ApiService.SaveConfigExecute(r)
}

/*
SaveConfig Save Config

Save the provided configuration to the server.
The app from the caller's token is used to determine which app the config belongs to.
The caller's camelCased slug (e.g., "test-user-slug" becomes "testUserSlug") is used as the config key automatically,
except for users who have the "config-svc:config:edit-on-behalf" permission (admins), who can specify any key they want.
Admins (users with the "config-svc:config:edit-on-behalf" permission) can also provide an "app" field in the request body to specify which app the config belongs to, while
non-admin users cannot specify the "app" field, the app associated with their token will be used.

The save performs a deep merge, that is:
- Nested objects are recursively merged rather than replaced.
- If a field exists in both the existing and the incoming config and both values are objects, their contents are merged.
- If a field exists in both but one or both values are not objects (e.g., string, number, array), the incoming value replaces the existing one.
- Fields present only in the incoming config are added.
- Fields present only in the existing config are preserved.
- Top-level and nested merges follow the same rules.

 @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
 @return ApiSaveConfigRequest
*/
func (a *ConfigSvcAPIService) SaveConfig(ctx context.Context) ApiSaveConfigRequest {
	return ApiSaveConfigRequest{
		ApiService: a,
		ctx: ctx,
	}
}

// Execute executes the request
//  @return map[string]interface{}
func (a *ConfigSvcAPIService) SaveConfigExecute(r ApiSaveConfigRequest) (map[string]interface{}, *http.Response, error) {
	var (
		localVarHTTPMethod   = http.MethodPut
		localVarPostBody     interface{}
		formFiles            []formFile
		localVarReturnValue  map[string]interface{}
	)

	localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ConfigSvcAPIService.SaveConfig")
	if err != nil {
		return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
	}

	localVarPath := localBasePath + "/config-svc/config"

	localVarHeaderParams := make(map[string]string)
	localVarQueryParams := url.Values{}
	localVarFormParams := url.Values{}
	if r.body == nil {
		return localVarReturnValue, nil, reportError("body is required and must be specified")
	}

	// to determine the Content-Type header
	localVarHTTPContentTypes := []string{"application/json"}

	// set Content-Type header
	localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
	if localVarHTTPContentType != "" {
		localVarHeaderParams["Content-Type"] = localVarHTTPContentType
	}

	// to determine the Accept header
	localVarHTTPHeaderAccepts := []string{"application/json"}

	// set Accept header
	localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
	if localVarHTTPHeaderAccept != "" {
		localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
	}
	// body params
	localVarPostBody = r.body
	if r.ctx != nil {
		// API Key Authentication
		if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok {
			if apiKey, ok := auth["BearerAuth"]; ok {
				var key string
				if apiKey.Prefix != "" {
					key = apiKey.Prefix + " " + apiKey.Key
				} else {
					key = apiKey.Key
				}
				localVarHeaderParams["Authorization"] = key
			}
		}
	}
	req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
	if err != nil {
		return localVarReturnValue, nil, err
	}

	localVarHTTPResponse, err := a.client.callAPI(req)
	if err != nil || localVarHTTPResponse == nil {
		return localVarReturnValue, localVarHTTPResponse, err
	}

	localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
	localVarHTTPResponse.Body.Close()
	localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
	if err != nil {
		return localVarReturnValue, localVarHTTPResponse, err
	}

	if localVarHTTPResponse.StatusCode >= 300 {
		newErr := &GenericOpenAPIError{
			body:  localVarBody,
			error: localVarHTTPResponse.Status,
		}
		if localVarHTTPResponse.StatusCode == 401 {
			var v string
			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
			if err != nil {
				newErr.error = err.Error()
				return localVarReturnValue, localVarHTTPResponse, newErr
			}
					newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
					newErr.model = v
			return localVarReturnValue, localVarHTTPResponse, newErr
		}
		if localVarHTTPResponse.StatusCode == 500 {
			var v string
			err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
			if err != nil {
				newErr.error = err.Error()
				return localVarReturnValue, localVarHTTPResponse, newErr
			}
					newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
					newErr.model = v
		}
		return localVarReturnValue, localVarHTTPResponse, newErr
	}

	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
	if err != nil {
		newErr := &GenericOpenAPIError{
			body:  localVarBody,
			error: err.Error(),
		}
		return localVarReturnValue, localVarHTTPResponse, newErr
	}

	return localVarReturnValue, localVarHTTPResponse, nil
}
