//go:build go1.18
// +build go1.18

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

package azcontainerregistry

import (
	"context"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
	"net/http"
	"net/url"
	"strings"
)

// AuthenticationClient contains the methods for the Authentication group.
// Don't use this type directly, use a constructor function instead.
type AuthenticationClient struct {
	internal *azcore.Client
	endpoint string
}

// ExchangeAADAccessTokenForACRRefreshToken - Exchange AAD tokens for an ACR refresh Token
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - grantType - Can take a value of accesstokenrefreshtoken, or accesstoken, or refresh_token
//   - service - Indicates the name of your Azure container registry.
//   - options - AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions contains the optional parameters for the
//     AuthenticationClient.ExchangeAADAccessTokenForACRRefreshToken method.
func (client *AuthenticationClient) ExchangeAADAccessTokenForACRRefreshToken(ctx context.Context, grantType PostContentSchemaGrantType, service string, options *AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions) (AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "AuthenticationClient.ExchangeAADAccessTokenForACRRefreshToken", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.exchangeAADAccessTokenForACRRefreshTokenCreateRequest(ctx, grantType, service, options)
	if err != nil {
		return AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusOK) {
		err = runtime.NewResponseError(httpResp)
		return AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}, err
	}
	resp, err := client.exchangeAADAccessTokenForACRRefreshTokenHandleResponse(httpResp)
	return resp, err
}

// exchangeAADAccessTokenForACRRefreshTokenCreateRequest creates the ExchangeAADAccessTokenForACRRefreshToken request.
func (client *AuthenticationClient) exchangeAADAccessTokenForACRRefreshTokenCreateRequest(ctx context.Context, grantType PostContentSchemaGrantType, service string, options *AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenOptions) (*policy.Request, error) {
	urlPath := "/oauth2/exchange"
	req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("api-version", "2021-07-01")
	req.Raw().URL.RawQuery = reqQP.Encode()
	req.Raw().Header["Accept"] = []string{"application/json"}
	formData := url.Values{}
	formData.Set("grant_type", string(grantType))
	formData.Set("service", service)
	if options != nil && options.Tenant != nil {
		formData.Set("tenant", *options.Tenant)
	}
	if options != nil && options.RefreshToken != nil {
		formData.Set("refresh_token", *options.RefreshToken)
	}
	if options != nil && options.AccessToken != nil {
		formData.Set("access_token", *options.AccessToken)
	}
	body := streaming.NopCloser(strings.NewReader(formData.Encode()))
	if err := req.SetBody(body, "application/x-www-form-urlencoded"); err != nil {
		return nil, err
	}
	return req, nil
}

// exchangeAADAccessTokenForACRRefreshTokenHandleResponse handles the ExchangeAADAccessTokenForACRRefreshToken response.
func (client *AuthenticationClient) exchangeAADAccessTokenForACRRefreshTokenHandleResponse(resp *http.Response) (AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse, error) {
	result := AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}
	if err := runtime.UnmarshalAsJSON(resp, &result.ACRRefreshToken); err != nil {
		return AuthenticationClientExchangeAADAccessTokenForACRRefreshTokenResponse{}, err
	}
	return result, nil
}

// ExchangeACRRefreshTokenForACRAccessToken - Exchange ACR Refresh token for an ACR Access Token
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - service - Indicates the name of your Azure container registry.
//   - scope - Which is expected to be a valid scope, and can be specified more than once for multiple scope requests. You obtained
//     this from the Www-Authenticate response header from the challenge.
//   - refreshToken - Must be a valid ACR refresh token
//   - options - AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions contains the optional parameters for the
//     AuthenticationClient.ExchangeACRRefreshTokenForACRAccessToken method.
func (client *AuthenticationClient) ExchangeACRRefreshTokenForACRAccessToken(ctx context.Context, service string, scope string, refreshToken string, options *AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions) (AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "AuthenticationClient.ExchangeACRRefreshTokenForACRAccessToken", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.exchangeACRRefreshTokenForACRAccessTokenCreateRequest(ctx, service, scope, refreshToken, options)
	if err != nil {
		return AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusOK) {
		err = runtime.NewResponseError(httpResp)
		return AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}, err
	}
	resp, err := client.exchangeACRRefreshTokenForACRAccessTokenHandleResponse(httpResp)
	return resp, err
}

// exchangeACRRefreshTokenForACRAccessTokenCreateRequest creates the ExchangeACRRefreshTokenForACRAccessToken request.
func (client *AuthenticationClient) exchangeACRRefreshTokenForACRAccessTokenCreateRequest(ctx context.Context, service string, scope string, refreshToken string, options *AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenOptions) (*policy.Request, error) {
	urlPath := "/oauth2/token"
	req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("api-version", "2021-07-01")
	req.Raw().URL.RawQuery = reqQP.Encode()
	req.Raw().Header["Accept"] = []string{"application/json"}
	formData := url.Values{}
	formData.Set("service", service)
	formData.Set("scope", scope)
	formData.Set("refresh_token", refreshToken)
	if options != nil && options.GrantType != nil {
		formData.Set("grant_type", string(*options.GrantType))
	}
	body := streaming.NopCloser(strings.NewReader(formData.Encode()))
	if err := req.SetBody(body, "application/x-www-form-urlencoded"); err != nil {
		return nil, err
	}
	return req, nil
}

// exchangeACRRefreshTokenForACRAccessTokenHandleResponse handles the ExchangeACRRefreshTokenForACRAccessToken response.
func (client *AuthenticationClient) exchangeACRRefreshTokenForACRAccessTokenHandleResponse(resp *http.Response) (AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse, error) {
	result := AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}
	if err := runtime.UnmarshalAsJSON(resp, &result.ACRAccessToken); err != nil {
		return AuthenticationClientExchangeACRRefreshTokenForACRAccessTokenResponse{}, err
	}
	return result, nil
}
