package azuresdkhacks

// 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.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"

	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/date"
	"github.com/Azure/go-autorest/autorest/to"
	"github.com/Azure/go-autorest/tracing"
)

// The package's fully qualified name.
const fqdn = "github.com/Azure/azure-sdk-for-go/services/appconfiguration/1.0/appconfiguration"

// KeyValue ...
type KeyValue struct {
	autorest.Response `json:"-"`
	Key               *string            `json:"key,omitempty"`
	Label             *string            `json:"label,omitempty"`
	ContentType       *string            `json:"content_type,omitempty"`
	Value             *string            `json:"value,omitempty"`
	LastModified      *date.Time         `json:"last_modified,omitempty"`
	Tags              map[string]*string `json:"tags"`
	Locked            *bool              `json:"locked,omitempty"`
	Etag              *string            `json:"etag,omitempty"`
}

// MarshalJSON is the custom marshaler for KeyValue.
func (kv KeyValue) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if kv.Key != nil {
		objectMap["key"] = kv.Key
	}
	if kv.Label != nil {
		objectMap["label"] = kv.Label
	}
	if kv.ContentType != nil {
		objectMap["content_type"] = kv.ContentType
	}
	if kv.Value != nil {
		objectMap["value"] = kv.Value
	}
	if kv.LastModified != nil {
		objectMap["last_modified"] = kv.LastModified
	}
	if kv.Tags != nil {
		objectMap["tags"] = kv.Tags
	}
	if kv.Locked != nil {
		objectMap["locked"] = kv.Locked
	}
	if kv.Etag != nil {
		objectMap["etag"] = kv.Etag
	}
	return json.Marshal(objectMap)
}

// KeyValueListResult the result of a list request.
type KeyValueListResult struct {
	autorest.Response `json:"-"`
	// Items - The collection value.
	Items *[]KeyValue `json:"items,omitempty"`
	// NextLink - The URI that can be used to request the next set of paged results.
	NextLink *string `json:"@nextLink,omitempty"`
}

// KeyValueListResultIterator provides access to a complete listing of KeyValue values.
type KeyValueListResultIterator struct {
	i    int
	page KeyValueListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *KeyValueListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/KeyValueListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *KeyValueListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter KeyValueListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter KeyValueListResultIterator) Response() KeyValueListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter KeyValueListResultIterator) Value() KeyValue {
	if !iter.page.NotDone() {
		return KeyValue{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the KeyValueListResultIterator type.
func NewKeyValueListResultIterator(page KeyValueListResultPage) KeyValueListResultIterator {
	return KeyValueListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (kvlr KeyValueListResult) IsEmpty() bool {
	return kvlr.Items == nil || len(*kvlr.Items) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (kvlr KeyValueListResult) hasNextLink() bool {
	return kvlr.NextLink != nil && len(*kvlr.NextLink) != 0
}

// keyValueListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (kvlr KeyValueListResult) keyValueListResultPreparer(ctx context.Context, endpoint string) (*http.Request, error) {
	if !kvlr.hasNextLink() {
		return nil, nil
	}

	nextLinkWithEndpoint := *kvlr.NextLink
	if !strings.HasPrefix(*kvlr.NextLink, endpoint) {
		nextLinkWithEndpoint = fmt.Sprintf("%s%s", endpoint, *kvlr.NextLink)
	}

	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(&nextLinkWithEndpoint)))
}

// KeyValueListResultPage contains a page of KeyValue values.
type KeyValueListResultPage struct {
	fn   func(context.Context, KeyValueListResult) (KeyValueListResult, error)
	kvlr KeyValueListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *KeyValueListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/KeyValueListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.kvlr)
		if err != nil {
			return err
		}
		page.kvlr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *KeyValueListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page KeyValueListResultPage) NotDone() bool {
	return !page.kvlr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page KeyValueListResultPage) Response() KeyValueListResult {
	return page.kvlr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page KeyValueListResultPage) Values() []KeyValue {
	if page.kvlr.IsEmpty() {
		return nil
	}
	return *page.kvlr.Items
}

// Creates a new instance of the KeyValueListResultPage type.
func NewKeyValueListResultPage(cur KeyValueListResult, getNextPage func(context.Context, KeyValueListResult) (KeyValueListResult, error)) KeyValueListResultPage {
	return KeyValueListResultPage{
		fn:   getNextPage,
		kvlr: cur,
	}
}
