<commit_before>package azure

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"reflect"
	"strconv"
	"strings"
	"time"

	"github.com/hashicorp/go-retryablehttp"
	"github.com/mitchellh/mapstructure"
)

type Request struct {
	URI      *string
	location *string
	tags     *map[string]*string
	etag     *string
	Command  APICall

	client *Client
}

func readLocation(req interface{}) (string, bool) {
	var value reflect.Value
	if reflect.ValueOf(req).Kind() == reflect.Ptr {
		value = reflect.ValueOf(req).Elem()
	} else {
		value = reflect.ValueOf(req)
	}

	for i := 0; i < value.NumField(); i++ { // iterates through every struct type field
		tag := value.Type().Field(i).Tag // returns the tag string
		if tag.Get("riviera") == "location" {
			return value.Field(i).String(), true
		}
	}
	return "", false
}

func readTags(req interface{}) (map[string]*string, bool) {
	var value reflect.Value
	if reflect.ValueOf(req).Kind() == reflect.Ptr {
		value = reflect.ValueOf(req).Elem()
	} else {
		value = reflect.ValueOf(req)
	}

	for i := 0; i < value.NumField(); i++ { // iterates through every struct type field
		tag := value.Type().Field(i).Tag // returns the tag string
		if tag.Get("riviera") == "tags" {
			tags := value.Field(i)
			return tags.Interface().(map[string]*string), true
		}
	}
	return make(map[string]*string), false
}

func (request *Request) pollForAsynchronousResponse(acceptedResponse *http.Response) (*http.Response, error) {
	var resp *http.Response = acceptedResponse

	for {
		if resp.StatusCode != http.StatusAccepted {
			return resp, nil
		}

		if retryAfter := resp.Header.Get("Retry-After"); retryAfter != "" {
			retryTime, err := strconv.Atoi(strings.TrimSpace(retryAfter))
			if err != nil {
				return nil, err
			}

			request.client.logger.Printf("[INFO] Polling pausing for %d seconds as per Retry-After header", retryTime)
			time.Sleep(time.Duration(retryTime) * time.Second)
		}

		pollLocation, err := resp.Location()
		if err != nil {
			return nil, err
		}

		request.client.logger.Printf("[INFO] Polling %q for operation completion", pollLocation.String())
		req, err := retryablehttp.NewRequest("GET", pollLocation.String(), bytes.NewReader([]byte{}))
		if err != nil {
			return nil, err
		}

		err = request.client.tokenRequester.addAuthorizationToRequest(req)
		if err != nil {
			return nil, err
		}

		resp, err := request.client.httpClient.Do(req)
		if err != nil {
			return nil, err
		}
		if resp.StatusCode == http.StatusAccepted {
			continue
		}

		return resp, err
	}
}

func (r *Request) Execute() (*Response, error) {
	apiInfo := r.Command.APIInfo()

	var urlString string

	// Base URL should already be validated by now so Parse is safe without error handling
	urlObj, _ := url.Parse(r.client.BaseUrl)

	// Determine whether to use the URLPathFunc or the URI explictly set in the request
	if r.URI == nil {
		urlObj.Path = fmt.Sprintf("/subscriptions/%s/%s", r.client.subscriptionID, strings.TrimPrefix(apiInfo.URLPathFunc(), "/"))
		urlString = urlObj.String()
	} else {
		urlObj.Path = *r.URI
		urlString = urlObj.String()
	}

	// Encode the request body if necessary
	body := bytes.NewReader([]byte{})
	if apiInfo.HasBody() {
		bodyStruct := struct {
			Location   *string             `json:"location,omitempty"`
			Tags       *map[string]*string `json:"tags,omitempty"`
			Properties interface{}         `json:"properties"`
		}{
			Properties: r.Command,
		}

		if location, hasLocation := readLocation(r.Command); hasLocation {
			bodyStruct.Location = &location
		}
		if tags, hasTags := readTags(r.Command); hasTags {
			if len(tags) > 0 {
				bodyStruct.Tags = &tags<commit_msg>core: Correct misspelling<commit_after>package azure

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"reflect"
	"strconv"
	"strings"
	"time"

	"github.com/hashicorp/go-retryablehttp"
	"github.com/mitchellh/mapstructure"
)

type Request struct {
	URI      *string
	location *string
	tags     *map[string]*string
	etag     *string
	Command  APICall

	client *Client
}

func readLocation(req interface{}) (string, bool) {
	var value reflect.Value
	if reflect.ValueOf(req).Kind() == reflect.Ptr {
		value = reflect.ValueOf(req).Elem()
	} else {
		value = reflect.ValueOf(req)
	}

	for i := 0; i < value.NumField(); i++ { // iterates through every struct type field
		tag := value.Type().Field(i).Tag // returns the tag string
		if tag.Get("riviera") == "location" {
			return value.Field(i).String(), true
		}
	}
	return "", false
}

func readTags(req interface{}) (map[string]*string, bool) {
	var value reflect.Value
	if reflect.ValueOf(req).Kind() == reflect.Ptr {
		value = reflect.ValueOf(req).Elem()
	} else {
		value = reflect.ValueOf(req)
	}

	for i := 0; i < value.NumField(); i++ { // iterates through every struct type field
		tag := value.Type().Field(i).Tag // returns the tag string
		if tag.Get("riviera") == "tags" {
			tags := value.Field(i)
			return tags.Interface().(map[string]*string), true
		}
	}
	return make(map[string]*string), false
}

func (request *Request) pollForAsynchronousResponse(acceptedResponse *http.Response) (*http.Response, error) {
	var resp *http.Response = acceptedResponse

	for {
		if resp.StatusCode != http.StatusAccepted {
			return resp, nil
		}

		if retryAfter := resp.Header.Get("Retry-After"); retryAfter != "" {
			retryTime, err := strconv.Atoi(strings.TrimSpace(retryAfter))
			if err != nil {
				return nil, err
			}

			request.client.logger.Printf("[INFO] Polling pausing for %d seconds as per Retry-After header", retryTime)
			time.Sleep(time.Duration(retryTime) * time.Second)
		}

		pollLocation, err := resp.Location()
		if err != nil {
			return nil, err
		}

		request.client.logger.Printf("[INFO] Polling %q for operation completion", pollLocation.String())
		req, err := retryablehttp.NewRequest("GET", pollLocation.String(), bytes.NewReader([]byte{}))
		if err != nil {
			return nil, err
		}

		err = request.client.tokenRequester.addAuthorizationToRequest(req)
		if err != nil {
			return nil, err
		}

		resp, err := request.client.httpClient.Do(req)
		if err != nil {
			return nil, err
		}
		if resp.StatusCode == http.StatusAccepted {
			continue
		}

		return resp, err
	}
}

func (r *Request) Execute() (*Response, error) {
	apiInfo := r.Command.APIInfo()

	var urlString string

	// Base URL should already be validated by now so Parse is safe without error handling
	urlObj, _ := url.Parse(r.client.BaseUrl)

	// Determine whether to use the URLPathFunc or the URI explicitly set in the request
	if r.URI == nil {
		urlObj.Path = fmt.Sprintf("/subscriptions/%s/%s", r.client.subscriptionID, strings.TrimPrefix(apiInfo.URLPathFunc(), "/"))
		urlString = urlObj.String()
	} else {
		urlObj.Path = *r.URI
		urlString = urlObj.String()
	}

	// Encode the request body if necessary
	body := bytes.NewReader([]byte{})
	if apiInfo.HasBody() {
		bodyStruct := struct {
			Location   *string             `json:"location,omitempty"`
			Tags       *map[string]*string `json:"tags,omitempty"`
			Properties interface{}         `json:"properties"`
		}{
			Properties: r.Command,
		}

		if location, hasLocation := readLocation(r.Command); hasLocation {
			bodyStruct.Location = &location
		}
		if tags, hasTags := readTags(r.Command); hasTags {
			if len(tags) > 0 {
				bodyStruct.Tags = &tags
{'fraction_non_alphanumeric': 0.14344094809971394, 'fraction_numerical': 0.0008173273395995096, 'mean_word_length': 3.6380290587492103, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2590980', 'n_tokens_mistral': 2613, 'n_tokens_neox': 2417, 'n_words': 615}