// Code generated by "requestgen -method GET -url /v1/cryptocurrency/listings/latest -type ListingsLatestRequest -responseType Response -responseDataField Data -responseDataType []Data"; DO NOT EDIT.

package v1

import (
	"context"
	"encoding/json"
	"fmt"
	"net/url"
	"reflect"
	"regexp"
)

func (l *ListingsLatestRequest) SetStart(Start int) *ListingsLatestRequest {
	l.Start = &Start
	return l
}

func (l *ListingsLatestRequest) SetLimit(Limit int) *ListingsLatestRequest {
	l.Limit = &Limit
	return l
}

func (l *ListingsLatestRequest) SetPriceMin(PriceMin float64) *ListingsLatestRequest {
	l.PriceMin = &PriceMin
	return l
}

func (l *ListingsLatestRequest) SetPriceMax(PriceMax float64) *ListingsLatestRequest {
	l.PriceMax = &PriceMax
	return l
}

func (l *ListingsLatestRequest) SetMarketCapMin(MarketCapMin float64) *ListingsLatestRequest {
	l.MarketCapMin = &MarketCapMin
	return l
}

func (l *ListingsLatestRequest) SetMarketCapMax(MarketCapMax float64) *ListingsLatestRequest {
	l.MarketCapMax = &MarketCapMax
	return l
}

func (l *ListingsLatestRequest) SetVolume24HMin(Volume24HMin float64) *ListingsLatestRequest {
	l.Volume24HMin = &Volume24HMin
	return l
}

func (l *ListingsLatestRequest) SetVolume24HMax(Volume24HMax float64) *ListingsLatestRequest {
	l.Volume24HMax = &Volume24HMax
	return l
}

func (l *ListingsLatestRequest) SetCirculatingSupplyMin(CirculatingSupplyMin float64) *ListingsLatestRequest {
	l.CirculatingSupplyMin = &CirculatingSupplyMin
	return l
}

func (l *ListingsLatestRequest) SetCirculatingSupplyMax(CirculatingSupplyMax float64) *ListingsLatestRequest {
	l.CirculatingSupplyMax = &CirculatingSupplyMax
	return l
}

func (l *ListingsLatestRequest) SetPercentChange24HMin(PercentChange24HMin float64) *ListingsLatestRequest {
	l.PercentChange24HMin = &PercentChange24HMin
	return l
}

func (l *ListingsLatestRequest) SetPercentChange24HMax(PercentChange24HMax float64) *ListingsLatestRequest {
	l.PercentChange24HMax = &PercentChange24HMax
	return l
}

func (l *ListingsLatestRequest) SetConvert(Convert string) *ListingsLatestRequest {
	l.Convert = &Convert
	return l
}

func (l *ListingsLatestRequest) SetConvertID(ConvertID string) *ListingsLatestRequest {
	l.ConvertID = &ConvertID
	return l
}

func (l *ListingsLatestRequest) SetSort(Sort string) *ListingsLatestRequest {
	l.Sort = &Sort
	return l
}

func (l *ListingsLatestRequest) SetSortDir(SortDir string) *ListingsLatestRequest {
	l.SortDir = &SortDir
	return l
}

func (l *ListingsLatestRequest) SetCryptocurrencyType(CryptocurrencyType string) *ListingsLatestRequest {
	l.CryptocurrencyType = &CryptocurrencyType
	return l
}

func (l *ListingsLatestRequest) SetTag(Tag string) *ListingsLatestRequest {
	l.Tag = &Tag
	return l
}

func (l *ListingsLatestRequest) SetAux(Aux string) *ListingsLatestRequest {
	l.Aux = &Aux
	return l
}

// GetQueryParameters builds and checks the query parameters and returns url.Values
func (l *ListingsLatestRequest) GetQueryParameters() (url.Values, error) {
	var params = map[string]interface{}{}
	// check Start field -> json key start
	if l.Start != nil {
		Start := *l.Start

		// assign parameter of Start
		params["start"] = Start
	} else {
		Start := 1

		// assign parameter of Start
		params["start"] = Start
	}
	// check Limit field -> json key limit
	if l.Limit != nil {
		Limit := *l.Limit

		// assign parameter of Limit
		params["limit"] = Limit
	} else {
		Limit := 100

		// assign parameter of Limit
		params["limit"] = Limit
	}
	// check PriceMin field -> json key price_min
	if l.PriceMin != nil {
		PriceMin := *l.PriceMin

		// assign parameter of PriceMin
		params["price_min"] = PriceMin
	} else {
	}
	// check PriceMax field -> json key price_max
	if l.PriceMax != nil {
		PriceMax := *l.PriceMax

		// assign parameter of PriceMax
		params["price_max"] = PriceMax
	} else {
	}
	// check MarketCapMin field -> json key market_cap_min
	if l.MarketCapMin != nil {
		MarketCapMin := *l.MarketCapMin

		// assign parameter of MarketCapMin
		params["market_cap_min"] = MarketCapMin
	} else {
	}
	// check MarketCapMax field -> json key market_cap_max
	if l.MarketCapMax != nil {
		MarketCapMax := *l.MarketCapMax

		// assign parameter of MarketCapMax
		params["market_cap_max"] = MarketCapMax
	} else {
	}
	// check Volume24HMin field -> json key volume_24h_min
	if l.Volume24HMin != nil {
		Volume24HMin := *l.Volume24HMin

		// assign parameter of Volume24HMin
		params["volume_24h_min"] = Volume24HMin
	} else {
	}
	// check Volume24HMax field -> json key volume_24h_max
	if l.Volume24HMax != nil {
		Volume24HMax := *l.Volume24HMax

		// assign parameter of Volume24HMax
		params["volume_24h_max"] = Volume24HMax
	} else {
	}
	// check CirculatingSupplyMin field -> json key circulating_supply_min
	if l.CirculatingSupplyMin != nil {
		CirculatingSupplyMin := *l.CirculatingSupplyMin

		// assign parameter of CirculatingSupplyMin
		params["circulating_supply_min"] = CirculatingSupplyMin
	} else {
	}
	// check CirculatingSupplyMax field -> json key circulating_supply_max
	if l.CirculatingSupplyMax != nil {
		CirculatingSupplyMax := *l.CirculatingSupplyMax

		// assign parameter of CirculatingSupplyMax
		params["circulating_supply_max"] = CirculatingSupplyMax
	} else {
	}
	// check PercentChange24HMin field -> json key percent_change_24h_min
	if l.PercentChange24HMin != nil {
		PercentChange24HMin := *l.PercentChange24HMin

		// assign parameter of PercentChange24HMin
		params["percent_change_24h_min"] = PercentChange24HMin
	} else {
	}
	// check PercentChange24HMax field -> json key percent_change_24h_max
	if l.PercentChange24HMax != nil {
		PercentChange24HMax := *l.PercentChange24HMax

		// assign parameter of PercentChange24HMax
		params["percent_change_24h_max"] = PercentChange24HMax
	} else {
	}
	// check Convert field -> json key convert
	if l.Convert != nil {
		Convert := *l.Convert

		// assign parameter of Convert
		params["convert"] = Convert
	} else {
	}
	// check ConvertID field -> json key convert_id
	if l.ConvertID != nil {
		ConvertID := *l.ConvertID

		// assign parameter of ConvertID
		params["convert_id"] = ConvertID
	} else {
	}
	// check Sort field -> json key sort
	if l.Sort != nil {
		Sort := *l.Sort

		// TEMPLATE check-valid-values
		switch Sort {
		case "name", "symbol", "date_added", "market_cap", "market_cap_strict", "price", "circulating_supply", "total_supply", "max_supply", "num_market_pairs", "volume_24h", "percent_change_1h", "percent_change_24h", "percent_change_7d", "market_cap_by_total_supply_strict", "volume_7d", "volume_30d":
			params["sort"] = Sort

		default:
			return nil, fmt.Errorf("sort value %v is invalid", Sort)

		}
		// END TEMPLATE check-valid-values

		// assign parameter of Sort
		params["sort"] = Sort
	} else {
		Sort := "market_cap"

		// assign parameter of Sort
		params["sort"] = Sort
	}
	// check SortDir field -> json key sort_dir
	if l.SortDir != nil {
		SortDir := *l.SortDir

		// TEMPLATE check-valid-values
		switch SortDir {
		case "asc", "desc":
			params["sort_dir"] = SortDir

		default:
			return nil, fmt.Errorf("sort_dir value %v is invalid", SortDir)

		}
		// END TEMPLATE check-valid-values

		// assign parameter of SortDir
		params["sort_dir"] = SortDir
	} else {
	}
	// check CryptocurrencyType field -> json key cryptocurrency_type
	if l.CryptocurrencyType != nil {
		CryptocurrencyType := *l.CryptocurrencyType

		// TEMPLATE check-valid-values
		switch CryptocurrencyType {
		case "all", "coins", "tokens":
			params["cryptocurrency_type"] = CryptocurrencyType

		default:
			return nil, fmt.Errorf("cryptocurrency_type value %v is invalid", CryptocurrencyType)

		}
		// END TEMPLATE check-valid-values

		// assign parameter of CryptocurrencyType
		params["cryptocurrency_type"] = CryptocurrencyType
	} else {
		CryptocurrencyType := "all"

		// assign parameter of CryptocurrencyType
		params["cryptocurrency_type"] = CryptocurrencyType
	}
	// check Tag field -> json key tag
	if l.Tag != nil {
		Tag := *l.Tag

		// TEMPLATE check-valid-values
		switch Tag {
		case "all", "defi", "filesharing":
			params["tag"] = Tag

		default:
			return nil, fmt.Errorf("tag value %v is invalid", Tag)

		}
		// END TEMPLATE check-valid-values

		// assign parameter of Tag
		params["tag"] = Tag
	} else {
		Tag := "all"

		// assign parameter of Tag
		params["tag"] = Tag
	}
	// check Aux field -> json key aux
	if l.Aux != nil {
		Aux := *l.Aux

		// assign parameter of Aux
		params["aux"] = Aux
	} else {
		Aux := "num_market_pairs,cmc_rank,date_added,tags,platform,max_supply,circulating_supply,total_supply"

		// assign parameter of Aux
		params["aux"] = Aux
	}

	query := url.Values{}
	for _k, _v := range params {
		query.Add(_k, fmt.Sprintf("%v", _v))
	}

	return query, nil
}

// GetParameters builds and checks the parameters and return the result in a map object
func (l *ListingsLatestRequest) GetParameters() (map[string]interface{}, error) {
	var params = map[string]interface{}{}

	return params, nil
}

// GetParametersQuery converts the parameters from GetParameters into the url.Values format
func (l *ListingsLatestRequest) GetParametersQuery() (url.Values, error) {
	query := url.Values{}

	params, err := l.GetParameters()
	if err != nil {
		return query, err
	}

	for _k, _v := range params {
		if l.isVarSlice(_v) {
			l.iterateSlice(_v, func(it interface{}) {
				query.Add(_k+"[]", fmt.Sprintf("%v", it))
			})
		} else {
			query.Add(_k, fmt.Sprintf("%v", _v))
		}
	}

	return query, nil
}

// GetParametersJSON converts the parameters from GetParameters into the JSON format
func (l *ListingsLatestRequest) GetParametersJSON() ([]byte, error) {
	params, err := l.GetParameters()
	if err != nil {
		return nil, err
	}

	return json.Marshal(params)
}

// GetSlugParameters builds and checks the slug parameters and return the result in a map object
func (l *ListingsLatestRequest) GetSlugParameters() (map[string]interface{}, error) {
	var params = map[string]interface{}{}

	return params, nil
}

func (l *ListingsLatestRequest) applySlugsToUrl(url string, slugs map[string]string) string {
	for _k, _v := range slugs {
		needleRE := regexp.MustCompile(":" + _k + "\\b")
		url = needleRE.ReplaceAllString(url, _v)
	}

	return url
}

func (l *ListingsLatestRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
	sliceValue := reflect.ValueOf(slice)
	for _i := 0; _i < sliceValue.Len(); _i++ {
		it := sliceValue.Index(_i).Interface()
		_f(it)
	}
}

func (l *ListingsLatestRequest) isVarSlice(_v interface{}) bool {
	rt := reflect.TypeOf(_v)
	switch rt.Kind() {
	case reflect.Slice:
		return true
	}
	return false
}

func (l *ListingsLatestRequest) GetSlugsMap() (map[string]string, error) {
	slugs := map[string]string{}
	params, err := l.GetSlugParameters()
	if err != nil {
		return slugs, nil
	}

	for _k, _v := range params {
		slugs[_k] = fmt.Sprintf("%v", _v)
	}

	return slugs, nil
}

func (l *ListingsLatestRequest) Do(ctx context.Context) ([]Data, error) {

	// no body params
	var params interface{}
	query, err := l.GetQueryParameters()
	if err != nil {
		return nil, err
	}

	apiURL := "/v1/cryptocurrency/listings/latest"

	req, err := l.Client.NewAuthenticatedRequest(ctx, "GET", apiURL, query, params)
	if err != nil {
		return nil, err
	}

	response, err := l.Client.SendRequest(req)
	if err != nil {
		return nil, err
	}

	var apiResponse Response
	if err := response.DecodeJSON(&apiResponse); err != nil {
		return nil, err
	}
	var data []Data
	if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
		return nil, err
	}
	return data, nil
}
