/*
Mender API

Combined API specification for the features of the different Mender backend services, suitable for code generation applications 

API version: 1
Contact: support@mender.io
*/

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

package client

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


type DeviceAuthenticationDeviceAPIAPI interface {

	/*
	DeviceAuthAuthenticateDevice Submit an authentication request

	The device presents its unique identity data and public key, and signs the request with its private key.
If the request is valid and the device is known to the system, a valid JWT authentication token is issued.

Unless the device is pre-authorized, the very first authentication request from a device will
always result in a 'HTTP 401 Unauthorized' response. At the same time, the identity data is recorded for
later inspection by the user, who can then explicitly accept or reject the device via the web GUI.
A subsequent authentication request will reflect this decision.

Note that when the JWT expires, the device must renew the JWT by sending a new authentication request.


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

	// DeviceAuthAuthenticateDeviceExecute executes the request
	//  @return string
	DeviceAuthAuthenticateDeviceExecute(r ApiDeviceAuthAuthenticateDeviceRequest) (string, *http.Response, error)
}

// DeviceAuthenticationDeviceAPIAPIService DeviceAuthenticationDeviceAPIAPI service
type DeviceAuthenticationDeviceAPIAPIService service

type ApiDeviceAuthAuthenticateDeviceRequest struct {
	ctx context.Context
	ApiService DeviceAuthenticationDeviceAPIAPI
	xMENSignature *string
	authRequest *AuthRequest
}

// Request signature. The request signature depends on the public key submitted in the AuthRequest. A summary of signature algorithms and format follows: | Type       | Digest              | Format                   | Algorithm    | |------------|---------------------|--------------------------|--------------| | RSA        | SHA256(AuthRequest) | Base64(Signature)        | [RFC2313]    | | ECDSA      | SHA256(AuthRequest) | Base64(ASN.1(SEQ{R, S})) | [ANSI x9.62] | | Ed25519    | AuthRequest         | Base64(Signature)        | [RFC8032]    | *Remark:* For ECDSA, the signature constitutes two integers (R and S) in which case the binary signature is taken as the ASN.1 sequence of the two numbers in the given order. 
func (r ApiDeviceAuthAuthenticateDeviceRequest) XMENSignature(xMENSignature string) ApiDeviceAuthAuthenticateDeviceRequest {
	r.xMENSignature = &xMENSignature
	return r
}

func (r ApiDeviceAuthAuthenticateDeviceRequest) AuthRequest(authRequest AuthRequest) ApiDeviceAuthAuthenticateDeviceRequest {
	r.authRequest = &authRequest
	return r
}

func (r ApiDeviceAuthAuthenticateDeviceRequest) Execute() (string, *http.Response, error) {
	return r.ApiService.DeviceAuthAuthenticateDeviceExecute(r)
}

/*
DeviceAuthAuthenticateDevice Submit an authentication request

The device presents its unique identity data and public key, and signs the request with its private key.
If the request is valid and the device is known to the system, a valid JWT authentication token is issued.

Unless the device is pre-authorized, the very first authentication request from a device will
always result in a 'HTTP 401 Unauthorized' response. At the same time, the identity data is recorded for
later inspection by the user, who can then explicitly accept or reject the device via the web GUI.
A subsequent authentication request will reflect this decision.

Note that when the JWT expires, the device must renew the JWT by sending a new authentication request.


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

// Execute executes the request
//  @return string
func (a *DeviceAuthenticationDeviceAPIAPIService) DeviceAuthAuthenticateDeviceExecute(r ApiDeviceAuthAuthenticateDeviceRequest) (string, *http.Response, error) {
	var (
		localVarHTTPMethod   = http.MethodPost
		localVarPostBody     interface{}
		formFiles            []formFile
		localVarReturnValue  string
	)

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

	localVarPath := localBasePath + "/api/devices/v1/authentication/auth_requests"

	localVarHeaderParams := make(map[string]string)
	localVarQueryParams := url.Values{}
	localVarFormParams := url.Values{}
	if r.xMENSignature == nil {
		return localVarReturnValue, nil, reportError("xMENSignature is required and must be specified")
	}
	if r.authRequest == nil {
		return localVarReturnValue, nil, reportError("authRequest 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
	}
	parameterAddToHeaderOrQuery(localVarHeaderParams, "X-MEN-Signature", r.xMENSignature, "simple", "")
	// body params
	localVarPostBody = r.authRequest
	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 a.client.cfg.ResponseMiddleware != nil {
		err = a.client.cfg.ResponseMiddleware(localVarHTTPResponse, localVarBody)
		if err != nil {
			return localVarReturnValue, localVarHTTPResponse, err
		}
	}

	if localVarHTTPResponse.StatusCode >= 300 {
		newErr := &GenericOpenAPIError{
			body:  localVarBody,
			error: localVarHTTPResponse.Status,
		}
		if localVarHTTPResponse.StatusCode == 400 {
			var v Error
			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 == 401 {
			var v Error
			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 Error
			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 == 503 {
			var v Error
			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
}
