<commit_before>package fastly

import (
	"fmt"
	"sort"
)

// Backend represents a backend response from the Fastly API.
type Backend struct {
	ServiceID string `mapstructure:"service_id"`
	Version   string `mapstructure:"version"`

	Name                string   `mapstructure:"name"`
	Address             string   `mapstructure:"address"`
	Port                uint     `mapstructure:"port"`
	ConnectTimeout      uint     `mapstructure:"connect_timeout"`
	MaxConn             uint     `mapstructure:"max_conn"`
	ErrorThreshold      uint     `mapstructure:"error_threshold"`
	FirstByteTimeout    uint     `mapstructure:"first_byte_timeout"`
	BetweenBytesTimeout uint     `mapstructure:"between_bytes_timeout"`
	AutoLoadbalance     bool     `mapstructure:"auto_loadbalance"`
	Weight              uint     `mapstructure:"weight"`
	RequestCondition    string   `mapstructure:"request_condition"`
	HealthCheck         string   `mapstructure:"healthcheck"`
	Hostname            string   `mapstructure:"hostname"`
	Shield              string   `mapstructure:"shield"`
	UseSSL              bool     `mapstructure:"use_ssl"`
	SSLCheckCert        bool     `mapstructure:"ssl_check_cert"`
	SSLHostname         string   `mapstructure:"ssl_hostname"`
	SSLCertHostname     string   `mapstructure:"ssl_cert_hostname"`
	SSLSNIHostname      string   `mapstructure:"ssl_sni_hostname"`
	MinTLSVersion       string   `mapstructure:"min_tls_version"`
	MaxTLSVersion       string   `mapstructure:"max_tls_version"`
	SSLCiphers          []string `mapstructure:"ssl_ciphers"`
}

// backendsByName is a sortable list of backends.
type backendsByName []*Backend

// Len, Swap, and Less implement the sortable interface.
func (s backendsByName) Len() int      { return len(s) }
func (s backendsByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s backendsByName) Less(i, j int) bool {
	return s[i].Name < s[j].Name
}

// ListBackendsInput is used as input to the ListBackends function.
type ListBackendsInput struct {
	// Service is the ID of the service (required).
	Service string

	// Version is the specific configuration version (required).
	Version string
}

// ListBackends returns the list of backends for the configuration version.
func (c *Client) ListBackends(i *ListBackendsInput) ([]*Backend, error) {
	if i.Service == "" {
		return nil, ErrMissingService
	}

	if i.Version == "" {
		return nil, ErrMissingVersion
	}

	path := fmt.Sprintf("/service/%s/version/%s/backend", i.Service, i.Version)
	resp, err := c.Get(path, nil)
	if err != nil {
		return nil, err
	}

	var bs []*Backend
	if err := decodeJSON(&bs, resp.Body); err != nil {
		return nil, err
	}
	sort.Stable(backendsByName(bs))
	return bs, nil
}

// CreateBackendInput is used as input to the CreateBackend function.
type CreateBackendInput struct {
	// Service is the ID of the service. Version is the specific configuration
	// version. Both fields are required.
	Service string
	Version string

	Name                string       `form:"name,omitempty"`
	Address             string       `form:"address,omitempty"`
	Port                uint         `form:"port,omitempty"`
	ConnectTimeout      uint         `form:"connect_timeout,omitempty"`
	MaxConn             uint         `form:"max_conn,omitempty"`
	ErrorThreshold      uint         `form:"error_threshold,omitempty"`
	FirstByteTimeout    uint         `form:"first_byte_timeout,omitempty"`
	BetweenBytesTimeout uint         `form:"between_bytes_timeout,omitempty"`
	AutoLoadbalance     *Compatibool `form:"auto_loadbalance,omitempty"`
	Weight              uint         `form:"weight,omitempty"`
	RequestCondition    string       `form:"request_condition,omitempty"`
	HealthCheck         string       `form:"healthcheck,omitempty"`
	Shield              string       `form:"shield,omitempty"`
	UseSSL              *Compatibool `form:"use_ssl,omitempty"`
	SSLCheckCert        *Compatibool `form:"ssl_check_cert,omitempty"`
	SSLHostname         string       `form:"ssl_hostname,omitempty"`
	SSLCertHostname     string       `form:"ssl_cert_hostname,omitempty"`
	SSLSNIHostname      string       `form:"ssl_sni_hostname,omitempty"`
	MinTLSVersion       string       `form:"min_tls_version,omitempty"`
	MaxTLSVersion       string       `form:"max_tls_version,omitempty"`
	SSLCiphers          []string     `form:"ssl_ciphers,omitempty"`
}

// CreateBackend creates a new Fastly backend.
func (c *Client) CreateBackend(i *CreateBackendInput) (*Backend, error) {
	if i.Service == "" {
		return nil, ErrMissingService
	}

	if i.Version == "" {
		return nil, ErrMissingVersion
	}

	path := fmt.Sprintf("/service/%s/version/%s/backend", i.Service, i.Version)
	resp, err := c.PostForm(path, i, nil)
	if err != nil {
		return nil, err
	}

	var b *Backend
	if err := decodeJSON(&b, resp.Body); err != nil {
		return nil, err
	}
	return b, nil
}

// GetBackendInput is used as input to the GetBackend function.
type GetBackendInput struct {
	// Service is the ID of the service. Version is the specific configuration
	// version. Both fields are required.
	Service string
	Version string

	// Name is the name of the backend to fetch.
	Name string
}

// GetBackend gets the backend configuration with the given parameters.
func (c *Client) GetBackend(i *GetBackendInput) (*Backend, error) {
	if i.Service == "" {
		return nil, ErrMissingService
	}

	if i.Version == "" {
		return nil, ErrMissingVersion
	}

	if i.Name == "" {
		return nil, ErrMissingName
	}

	path := fmt.Sprintf("/service/%s/version/%s/backend/%s", i.Service, i.Version, i.Name)
	resp, err := c.Get(path, nil)
	if err != nil {
		return nil, err
	}

	var b *Backend
	if err := decodeJSON(&b, resp.Body); err != nil {
		return nil, err
	}
	return b, nil
}

// UpdateBackendInput is used as input to the UpdateBackend function.
type UpdateBackendInput struct {
	// Service is the ID of the service. Version is the specific configuration
	// version. Both fields are required.
	Service string
	Version string

	// Name is the name of the backend to update.
	Name string

	NewName             string       `form:"name,omitempty"`
	Address             string       `form:"address,omitempty"`
	Port                uint         `form:"port,omitempty"`
	ConnectTimeout      uint         `form:"connect_timeout,omitempty"`
	MaxConn             uint         `form:"max_conn,omitempty"`
	ErrorThreshold      uint         `form:"error_threshold,omitempty"`
	FirstByteTimeout    uint         `form:"first_byte_timeout,omitempty"`
	BetweenBytesTimeout uint         `form:"between_bytes_timeout,omitempty"`
	AutoLoadbalance     *Compatibool `form:"auto_loadbalance,omitempty"`
	Weight              uint         `form:"weight,omitempty"`
	RequestCondition    string       `form:"request_condition,omitempty"`
	HealthCheck         string       `form:"healthcheck,omitempty"`
	Shield              string       `form:"shield,omitempty"`
	UseSSL              *Compatibool `form:"use_ssl,omitempty"`
	SSLCheckCert        *Compatibool `form:"ssl_check_cert,omitempty"`<commit_msg>Add additional SSL fields to backend<commit_after>package fastly

import (
	"fmt"
	"sort"
)

// Backend represents a backend response from the Fastly API.
type Backend struct {
	ServiceID string `mapstructure:"service_id"`
	Version   string `mapstructure:"version"`

	Name                string   `mapstructure:"name"`
	Address             string   `mapstructure:"address"`
	Port                uint     `mapstructure:"port"`
	ConnectTimeout      uint     `mapstructure:"connect_timeout"`
	MaxConn             uint     `mapstructure:"max_conn"`
	ErrorThreshold      uint     `mapstructure:"error_threshold"`
	FirstByteTimeout    uint     `mapstructure:"first_byte_timeout"`
	BetweenBytesTimeout uint     `mapstructure:"between_bytes_timeout"`
	AutoLoadbalance     bool     `mapstructure:"auto_loadbalance"`
	Weight              uint     `mapstructure:"weight"`
	RequestCondition    string   `mapstructure:"request_condition"`
	HealthCheck         string   `mapstructure:"healthcheck"`
	Hostname            string   `mapstructure:"hostname"`
	Shield              string   `mapstructure:"shield"`
	UseSSL              bool     `mapstructure:"use_ssl"`
	SSLCheckCert        bool     `mapstructure:"ssl_check_cert"`
	SSLCACert           string   `mapstructure:"ssl_ca_cert"`
	SSLClientCert       string   `mapstructure:"ssl_client_cert"`
	SSLClientKey        string   `mapstructure:"ssl_client_key"`
	SSLHostname         string   `mapstructure:"ssl_hostname"`
	SSLCertHostname     string   `mapstructure:"ssl_cert_hostname"`
	SSLSNIHostname      string   `mapstructure:"ssl_sni_hostname"`
	MinTLSVersion       string   `mapstructure:"min_tls_version"`
	MaxTLSVersion       string   `mapstructure:"max_tls_version"`
	SSLCiphers          []string `mapstructure:"ssl_ciphers"`
}

// backendsByName is a sortable list of backends.
type backendsByName []*Backend

// Len, Swap, and Less implement the sortable interface.
func (s backendsByName) Len() int      { return len(s) }
func (s backendsByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s backendsByName) Less(i, j int) bool {
	return s[i].Name < s[j].Name
}

// ListBackendsInput is used as input to the ListBackends function.
type ListBackendsInput struct {
	// Service is the ID of the service (required).
	Service string

	// Version is the specific configuration version (required).
	Version string
}

// ListBackends returns the list of backends for the configuration version.
func (c *Client) ListBackends(i *ListBackendsInput) ([]*Backend, error) {
	if i.Service == "" {
		return nil, ErrMissingService
	}

	if i.Version == "" {
		return nil, ErrMissingVersion
	}

	path := fmt.Sprintf("/service/%s/version/%s/backend", i.Service, i.Version)
	resp, err := c.Get(path, nil)
	if err != nil {
		return nil, err
	}

	var bs []*Backend
	if err := decodeJSON(&bs, resp.Body); err != nil {
		return nil, err
	}
	sort.Stable(backendsByName(bs))
	return bs, nil
}

// CreateBackendInput is used as input to the CreateBackend function.
type CreateBackendInput struct {
	// Service is the ID of the service. Version is the specific configuration
	// version. Both fields are required.
	Service string
	Version string

	Name                string       `form:"name,omitempty"`
	Address             string       `form:"address,omitempty"`
	Port                uint         `form:"port,omitempty"`
	ConnectTimeout      uint         `form:"connect_timeout,omitempty"`
	MaxConn             uint         `form:"max_conn,omitempty"`
	ErrorThreshold      uint         `form:"error_threshold,omitempty"`
	FirstByteTimeout    uint         `form:"first_byte_timeout,omitempty"`
	BetweenBytesTimeout uint         `form:"between_bytes_timeout,omitempty"`
	AutoLoadbalance     *Compatibool `form:"auto_loadbalance,omitempty"`
	Weight              uint         `form:"weight,omitempty"`
	RequestCondition    string       `form:"request_condition,omitempty"`
	HealthCheck         string       `form:"healthcheck,omitempty"`
	Shield              string       `form:"shield,omitempty"`
	UseSSL              *Compatibool `form:"use_ssl,omitempty"`
	SSLCheckCert        *Compatibool `form:"ssl_check_cert,omitempty"`
	SSLCACert           string       `form:"ssl_ca_cert,omitempty"`
	SSLClientCert       string       `form:"ssl_client_cert,omitempty"`
	SSLClientKey        string       `form:"ssl_client_key,omitempty"`
	SSLHostname         string       `form:"ssl_hostname,omitempty"`
	SSLCertHostname     string       `form:"ssl_cert_hostname,omitempty"`
	SSLSNIHostname      string       `form:"ssl_sni_hostname,omitempty"`
	MinTLSVersion       string       `form:"min_tls_version,omitempty"`
	MaxTLSVersion       string       `form:"max_tls_version,omitempty"`
	SSLCiphers          []string     `form:"ssl_ciphers,omitempty"`
}

// CreateBackend creates a new Fastly backend.
func (c *Client) CreateBackend(i *CreateBackendInput) (*Backend, error) {
	if i.Service == "" {
		return nil, ErrMissingService
	}

	if i.Version == "" {
		return nil, ErrMissingVersion
	}

	path := fmt.Sprintf("/service/%s/version/%s/backend", i.Service, i.Version)
	resp, err := c.PostForm(path, i, nil)
	if err != nil {
		return nil, err
	}

	var b *Backend
	if err := decodeJSON(&b, resp.Body); err != nil {
		return nil, err
	}
	return b, nil
}

// GetBackendInput is used as input to the GetBackend function.
type GetBackendInput struct {
	// Service is the ID of the service. Version is the specific configuration
	// version. Both fields are required.
	Service string
	Version string

	// Name is the name of the backend to fetch.
	Name string
}

// GetBackend gets the backend configuration with the given parameters.
func (c *Client) GetBackend(i *GetBackendInput) (*Backend, error) {
	if i.Service == "" {
		return nil, ErrMissingService
	}

	if i.Version == "" {
		return nil, ErrMissingVersion
	}

	if i.Name == "" {
		return nil, ErrMissingName
	}

	path := fmt.Sprintf("/service/%s/version/%s/backend/%s", i.Service, i.Version, i.Name)
	resp, err := c.Get(path, nil)
	if err != nil {
		return nil, err
	}

	var b *Backend
	if err := decodeJSON(&b, resp.Body); err != nil {
		return nil, err
	}
	return b, nil
}

// UpdateBackendInput is used as input to the UpdateBackend function.
type UpdateBackendInput struct {
	// Service is the ID of the service. Version is the specific configuration
	// version. Both fields are required.
	Service string
	Version string

	// Name is the name of the backend to update.
	Name string

	NewName             string       `form:"name,omitempty"`
	Address             string       `form:"address,omitempty"`
	Port                uint         `form:"port,omitempty"`
	ConnectTimeout      uint         `form:"connect_timeout,omitempty"`
	MaxConn             uint         `form:"max_conn,omitempty"`
	ErrorThreshold      uint         `form:"error_threshold,omitempty"`
	FirstByteTimeout    uint         `form:"first_byte_timeout,omitempty"`
	BetweenBytesTimeout uint         `form:"between_bytes_timeout,omitempty"`
	AutoLoadbalance     *Compatibool `form:"auto_loadbalance,omitempty"`
	Weight              uint         `form:"weight,omitempty"`
	RequestCondition    string       `form:"request_condition,omitempty"`
	HealthCheck         string       `form:"healthcheck,omitempty"`
	Shield              string       `form:"shield,omitempty"`
	UseSSL              *Compatibool `form:"use_ssl,omitempty"`
	SSLCheckCert        *Compatibool `form:"ssl_check_cert,omitempty"`
	SSLCACert           string       `form:"ssl_ca_cert,omitempty"`
	SSLClientCert       string       `form:"ssl_client_cert,omitempty"`
	SSLClientKey        string       `form:"ssl_client_key,omitempty"`
{'fraction_non_alphanumeric': 0.10137210731107925, 'fraction_numerical': 0.0, 'mean_word_length': 3.153671675645024, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '6142752', 'n_tokens_mistral': 4229, 'n_tokens_neox': 4208, 'n_words': 1161}