func NewNginxClientWithVersion(httpClient *http.Client, apiEndpoint string, version int) (*NginxClient, error) {
	if !versionSupported(version) {
		return nil, fmt.Errorf("API version %v is not supported by the client", version)
	}
	versions, err := getAPIVersions(httpClient, apiEndpoint)
	if err != nil {
		return nil, fmt.Errorf("error accessing the API: %w", err)
	}
	found := false
	for _, v := range *versions {
		if v == version {
			found = true
			break
		}
	}
	if !found {
		return nil, ErrUnsupportedVer
	}
	return &NginxClient{
		apiEndpoint: apiEndpoint,
		httpClient:  httpClient,
		version:     version,
	}, nil
}
NewNginxClientWithVersion creates an NginxClient with the given version of NGINX Plus API.
package client
import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"reflect"
	"strings"
	"time"
)
const (
	APIVersion = 5
	pathNotFoundCode  = "PathNotFound"
	streamContext     = true
	httpContext       = false
	defaultServerPort = "80"
)
var (
	supportedAPIVersions = versions{4, 5}
	defaultMaxConns    = 0
	defaultMaxFails    = 1
	defaultFailTimeout = "10s"
	defaultSlowStart   = "0s"
	defaultBackup      = false
	defaultDown        = false
	defaultWeight      = 1
)
var ErrUnsupportedVer = errors.New("API version of the client is not supported by running NGINX Plus")
type NginxClient struct {
	version     int
	apiEndpoint string
	httpClient  *http.Client
}
type versions []int
type UpstreamServer struct {
	ID          int    `json:"id,omitempty"`
	Server      string `json:"server"`
	MaxConns    *int   `json:"max_conns,omitempty"`
	MaxFails    *int   `json:"max_fails,omitempty"`
	FailTimeout string `json:"fail_timeout,omitempty"`
	SlowStart   string `json:"slow_start,omitempty"`
	Route       string `json:"route,omitempty"`
	Backup      *bool  `json:"backup,omitempty"`
	Down        *bool  `json:"down,omitempty"`
	Drain       bool   `json:"drain,omitempty"`
	Weight      *int   `json:"weight,omitempty"`
	Service     string `json:"service,omitempty"`
}
type StreamUpstreamServer struct {
	ID          int    `json:"id,omitempty"`
	Server      string `json:"server"`
	MaxConns    *int   `json:"max_conns,omitempty"`
	MaxFails    *int   `json:"max_fails,omitempty"`
	FailTimeout string `json:"fail_timeout,omitempty"`
	SlowStart   string `json:"slow_start,omitempty"`
	Backup      *bool  `json:"backup,omitempty"`
	Down        *bool  `json:"down,omitempty"`
	Weight      *int   `json:"weight,omitempty"`
	Service     string `json:"service,omitempty"`
}
type apiErrorResponse struct {
	Error     apiError
	RequestID string `json:"request_id"`
	Href      string
}
func (resp *apiErrorResponse) toString() string {
	return fmt.Sprintf("error.status=%v; error.text=%v; error.code=%v; request_id=%v; href=%v",
		resp.Error.Status, resp.Error.Text, resp.Error.Code, resp.RequestID, resp.Href)
}
type apiError struct {
	Status int
	Text   string
	Code   string
}
type internalError struct {
	apiError
	err string
}
func (internalError *internalError) Error() string {
	return internalError.err
}
func (internalError *internalError) Wrap(err string) *internalError {
	internalError.err = fmt.Sprintf("%v. %v", err, internalError.err)
	return internalError
}
type Stats struct {
	NginxInfo         NginxInfo
	Caches            Caches
	Processes         Processes
	Connections       Connections
	Slabs             Slabs
	HTTPRequests      HTTPRequests
	SSL               SSL
	ServerZones       ServerZones
	Upstreams         Upstreams
	StreamServerZones StreamServerZones
	StreamUpstreams   StreamUpstreams
	StreamZoneSync    *StreamZoneSync
	LocationZones     LocationZones
	Resolvers         Resolvers
}
type NginxInfo struct {
	Version         string
	Build           string
	Address         string
	Generation      uint64
	LoadTimestamp   string `json:"load_timestamp"`
	Timestamp       string
	ProcessID       uint64 `json:"pid"`
	ParentProcessID uint64 `json:"ppid"`
}
type Caches = map[string]HTTPCache
type HTTPCache struct {
	Size        uint64
	MaxSize     uint64 `json:"max_size"`
	Cold        bool
	Hit         CacheStats
	Stale       CacheStats
	Updating    CacheStats
	Revalidated CacheStats
	Miss        CacheStats
	Expired     ExtendedCacheStats
	Bypass      ExtendedCacheStats
}
type CacheStats struct {
	Responses uint64
	Bytes     uint64
}
type ExtendedCacheStats struct {
	CacheStats
	ResponsesWritten uint64 `json:"responses_written"`
	BytesWritten     uint64 `json:"bytes_written"`
}
type Connections struct {
	Accepted uint64
	Dropped  uint64
	Active   uint64
	Idle     uint64
}
type Slabs map[string]Slab
type Slab struct {
	Pages Pages
	Slots Slots
}
type Pages struct {
	Used uint64
	Free uint64
}
type Slots map[string]Slot
type Slot struct {
	Used  uint64
	Free  uint64
	Reqs  uint64
	Fails uint64
}
type HTTPRequests struct {
	Total   uint64
	Current uint64
}
type SSL struct {
	Handshakes       uint64
	HandshakesFailed uint64 `json:"handshakes_failed"`
	SessionReuses    uint64 `json:"session_reuses"`
}
type ServerZones map[string]ServerZone
type ServerZone struct {
	Processing uint64
	Requests   uint64
	Responses  Responses
	Discarded  uint64
	Received   uint64
	Sent       uint64
}
type StreamServerZones map[string]StreamServerZone
type StreamServerZone struct {
	Processing  uint64
	Connections uint64
	Sessions    Sessions
	Discarded   uint64
	Received    uint64
	Sent        uint64
}
type StreamZoneSync struct {
	Zones  map[string]SyncZone
	Status StreamZoneSyncStatus
}
type SyncZone struct {
	RecordsPending uint64 `json:"records_pending"`
	RecordsTotal   uint64 `json:"records_total"`
}
type StreamZoneSyncStatus struct {
	BytesIn     uint64 `json:"bytes_in"`
	MsgsIn      uint64 `json:"msgs_in"`
	MsgsOut     uint64 `json:"msgs_out"`
	BytesOut    uint64 `json:"bytes_out"`
	NodesOnline uint64 `json:"nodes_online"`
}
type Responses struct {
	Responses1xx uint64 `json:"1xx"`
	Responses2xx uint64 `json:"2xx"`
	Responses3xx uint64 `json:"3xx"`
	Responses4xx uint64 `json:"4xx"`
	Responses5xx uint64 `json:"5xx"`
	Total        uint64
}
type Sessions struct {
	Sessions2xx uint64 `json:"2xx"`
	Sessions4xx uint64 `json:"4xx"`
	Sessions5xx uint64 `json:"5xx"`
	Total       uint64
}
type Upstreams map[string]Upstream
type Upstream struct {
	Peers      []Peer
	Keepalives int
	Zombies    int
	Zone       string
	Queue      Queue
}
type StreamUpstreams map[string]StreamUpstream
type StreamUpstream struct {
	Peers   []StreamPeer
	Zombies int
	Zone    string
}
type Queue struct {
	Size      int
	MaxSize   int `json:"max_size"`
	Overflows uint64
}
type Peer struct {
	ID           int
	Server       string
	Service      string
	Name         string
	Backup       bool
	Weight       int
	State        string
	Active       uint64
	MaxConns     int `json:"max_conns"`
	Requests     uint64
	Responses    Responses
	Sent         uint64
	Received     uint64
	Fails        uint64
	Unavail      uint64
	HealthChecks HealthChecks `json:"health_checks"`
	Downtime     uint64
	Downstart    string
	Selected     string
	HeaderTime   uint64 `json:"header_time"`
	ResponseTime uint64 `json:"response_time"`
}
type StreamPeer struct {
	ID            int
	Server        string
	Service       string
	Name          string
	Backup        bool
	Weight        int
	State         string
	Active        uint64
	MaxConns      int `json:"max_conns"`
	Connections   uint64
	ConnectTime   int    `json:"connect_time"`
	FirstByteTime int    `json:"first_byte_time"`
	ResponseTime  uint64 `json:"response_time"`
	Sent          uint64
	Received      uint64
	Fails         uint64
	Unavail       uint64
	HealthChecks  HealthChecks `json:"health_checks"`
	Downtime      uint64
	Downstart     string
	Selected      string
}
type HealthChecks struct {
	Checks     uint64
	Fails      uint64
	Unhealthy  uint64
	LastPassed bool `json:"last_passed"`
}
type LocationZones map[string]LocationZone
type Resolvers map[string]Resolver
type LocationZone struct {
	Requests  int64
	Responses Responses
	Discarded int64
	Received  int64
	Sent      int64
}
type Resolver struct {
	Requests  ResolverRequests  `json:"requests"`
	Responses ResolverResponses `json:"responses"`
}
type ResolverRequests struct {
	Name int64
	Srv  int64
	Addr int64
}
type ResolverResponses struct {
	Noerror  int64
	Formerr  int64
	Servfail int64
	Nxdomain int64
	Notimp   int64
	Refused  int64
	Timedout int64
	Unknown  int64
}
type Processes struct {
	Respawned int64
}
func NewNginxClient(httpClient *http.Client, apiEndpoint string) (*NginxClient, error) {
	return NewNginxClientWithVersion(httpClient, apiEndpoint, APIVersion)
}