package lbs

import (
	"errors"

	"github.com/mitchellh/mapstructure"

	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
	"github.com/rackspace/gophercloud/rackspace/lb/v1/acl"
	"github.com/rackspace/gophercloud/rackspace/lb/v1/monitors"
	"github.com/rackspace/gophercloud/rackspace/lb/v1/nodes"
	"github.com/rackspace/gophercloud/rackspace/lb/v1/sessions"
	"github.com/rackspace/gophercloud/rackspace/lb/v1/throttle"
	"github.com/rackspace/gophercloud/rackspace/lb/v1/vips"
)

var (
	errNameRequired    = errors.New("Name is a required attribute")
	errTimeoutExceeded = errors.New("Timeout must be less than 120")
)

// ListOptsBuilder allows extensions to add additional parameters to the
// List request.
type ListOptsBuilder interface {
	ToLBListQuery() (string, error)
}

// ListOpts allows the filtering and sorting of paginated collections through
// the API.
type ListOpts struct {
	ChangesSince string `q:"changes-since"`
	Status       Status `q:"status"`
	NodeAddr     string `q:"nodeaddress"`
	Marker       string `q:"marker"`
	Limit        int    `q:"limit"`
}

// ToLBListQuery formats a ListOpts into a query string.
func (opts ListOpts) ToLBListQuery() (string, error) {
	q, err := gophercloud.BuildQueryString(opts)
	if err != nil {
		return "", err
	}
	return q.String(), nil
}

// List is the operation responsible for returning a paginated collection of
// load balancers. You may pass in a ListOpts struct to filter results.
func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
	url := rootURL(client)
	if opts != nil {
		query, err := opts.ToLBListQuery()
		if err != nil {
			return pagination.Pager{Err: err}
		}
		url += query
	}

	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
		return LBPage{pagination.LinkedPageBase{PageResult: r}}
	})
}

// CreateOptsBuilder is the interface options structs have to satisfy in order
// to be used in the main Create operation in this package. Since many
// extensions decorate or modify the common logic, it is useful for them to
// satisfy a basic interface in order for them to be used.
type CreateOptsBuilder interface {
	ToLBCreateMap() (map[string]interface{}, error)
}

// CreateOpts is the common options struct used in this package's Create
// operation.
type CreateOpts struct {
	// Required - name of the load balancer to create. The name must be 128
	// characters or fewer in length, and all UTF-8 characters are valid.
	Name string

	// Optional - nodes to be added.
	Nodes []nodes.Node

	// Required - protocol of the service that is being load balanced.
	// See http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/protocols.html
	// for a full list of supported protocols.
	Protocol string

	// Optional - enables or disables Half-Closed support for the load balancer.
	// Half-Closed support provides the ability for one end of the connection to
	// terminate its output, while still receiving data from the other end. Only
	// available for TCP/TCP_CLIENT_FIRST protocols.
	HalfClosed gophercloud.EnabledState

	// Optional - the type of virtual IPs you want associated with the load
	// balancer.
	VIPs []vips.VIP

	// Optional - the access list management feature allows fine-grained network
	// access controls to be applied to the load balancer virtual IP address.
	AccessList *acl.AccessList

	// Optional - algorithm that defines how traffic should be directed between
	// back-end nodes.
	Algorithm string

	// Optional - current connection logging configuration.
	ConnectionLogging *ConnectionLogging

	// Optional - specifies a limit on the number of connections per IP address
	// to help mitigate malicious or abusive traffic to your applications.
	ConnThrottle *throttle.ConnectionThrottle

	// Optional - the type of health monitor check to perform to ensure that the
	// service is performing properly.
	HealthMonitor *monitors.Monitor

	// Optional - arbitrary information that can be associated with each LB.
	Metadata map[string]interface{}

	// Optional - port number for the service you are load balancing.
	Port int

	// Optional - the timeout value for the load balancer and communications with
	// its nodes. Defaults to 30 seconds with a maximum of 120 seconds.
	Timeout int

	// Optional - specifies whether multiple requests from clients are directed
	// to the same node.
	SessionPersistence *sessions.SessionPersistence

	// Optional - enables or disables HTTP to HTTPS redirection for the load
	// balancer. When enabled, any HTTP request returns status code 301 (Moved
	// Permanently), and the requester is redirected to the requested URL via the
	// HTTPS protocol on port 443. For example, http://example.com/page.html
	// would be redirected to https://example.com/page.html. Only available for
	// HTTPS protocol (port=443), or HTTP protocol with a properly configured SSL
	// termination (secureTrafficOnly=true, securePort=443).
	HTTPSRedirect gophercloud.EnabledState
}

// ToLBCreateMap casts a CreateOpts struct to a map.
func (opts CreateOpts) ToLBCreateMap() (map[string]interface{}, error) {
	lb := make(map[string]interface{})

	if opts.Name == "" {
		return lb, errNameRequired
	}
	if opts.Timeout > 120 {
		return lb, errTimeoutExceeded
	}

	lb["name"] = opts.Name

	if len(opts.Nodes) > 0 {
		nodes := []map[string]interface{}{}
		for _, n := range opts.Nodes {
			nodes = append(nodes, map[string]interface{}{
				"address":   n.Address,
				"port":      n.Port,
				"condition": n.Condition,
			})
		}
		lb["nodes"] = nodes
	}

	if opts.Protocol != "" {
		lb["protocol"] = opts.Protocol
	}
	if opts.HalfClosed != nil {
		lb["halfClosed"] = opts.HalfClosed
	}
	if len(opts.VIPs) > 0 {
		lb["virtualIps"] = opts.VIPs
	}
	if opts.AccessList != nil {
		lb["accessList"] = &opts.AccessList
	}
	if opts.Algorithm != "" {
		lb["algorithm"] = opts.Algorithm
	}
	if opts.ConnectionLogging != nil {
		lb["connectionLogging"] = &opts.ConnectionLogging
	}
	if opts.ConnThrottle != nil {
		lb["connectionThrottle"] = &opts.ConnThrottle
	}
	if opts.HealthMonitor != nil {
		lb["healthMonitor"] = &opts.HealthMonitor
	}
	if len(opts.Metadata) != 0 {
		lb["metadata"] = opts.Metadata
	}
	if opts.Port > 0 {
		lb["port"] = opts.Port
	}
	if opts.Timeout > 0 {
		lb["timeout"] = opts.Timeout
	}
	if opts.SessionPersistence != nil {
		lb["sessionPersistence"] = &opts.SessionPersistence
	}
	if opts.HTTPSRedirect != nil {
		lb["httpsRedirect"] = &opts.HTTPSRedirect
	}

	return map[string]interface{}{"loadBalancer": lb}, nil
}

// Create is the operation responsible for asynchronously provisioning a new
// load balancer based on the configuration defined in CreateOpts. Once the
// request is validated and progress has started on the provisioning process, a
// response struct is returned. When extracted (with Extract()), you have
// to the load balancer's unique ID and status.
//
// Once an ID is attained, you can check on the progress of the operation by
// calling Get and passing in the ID. If the corresponding request cannot be
// fulfilled due to insufficient or invalid data, an HTTP 400 (Bad Request)
// error response is returned with information regarding the nature of the
// failure in the body of the response. Failures in the validation process are
// non-recoverable and require the caller to correct the cause of the failure.
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
	var res CreateResult

	reqBody, err := opts.ToLBCreateMap()
	if err != nil {
		res.Err = err
		return res
	}

	_, res.Err = c.Request("POST", rootURL(c), gophercloud.RequestOpts{
		JSONBody:     &reqBody,
		JSONResponse: &res.Body,
		OkCodes:      []int{202},
	})

	return res
}

// Get is the operation responsible for providing detailed information
// regarding a specific load balancer which is configured and associated with
// your account. This operation is not capable of returning details for a load
// balancer which has been deleted.
func Get(c *gophercloud.ServiceClient, id int) GetResult {
	var res GetResult

	_, res.Err = c.Request("GET", resourceURL(c, id), gophercloud.RequestOpts{
		JSONResponse: &res.Body,
		OkCodes:      []int{200},
	})

	return res
}

// BulkDelete removes all the load balancers referenced in the slice of IDs.
// Any and all configuration data associated with these load balancers is
// immediately purged and is not recoverable.
//
// If one of the items in the list cannot be removed due to its current status,
// a 400 Bad Request error is returned along with the IDs of the ones the
// system identified as potential failures for this request.
func BulkDelete(c *gophercloud.ServiceClient, ids []int) DeleteResult {
	var res DeleteResult

	if len(ids) > 10 || len(ids) == 0 {
		res.Err = errors.New("You must provide a minimum of 1 and a maximum of 10 LB IDs")
		return res
	}

	url := rootURL(c)
	url += gophercloud.IDSliceToQueryString("id", ids)

	_, res.Err = c.Request("DELETE", url, gophercloud.RequestOpts{
		OkCodes: []int{202},
	})

	return res
}

// Delete removes a single load balancer.
func Delete(c *gophercloud.ServiceClient, id int) DeleteResult {
	var res DeleteResult

	_, res.Err = c.Request("DELETE", resourceURL(c, id), gophercloud.RequestOpts{
		OkCodes: []int{202},
	})

	return res
}

// UpdateOptsBuilder represents a type that can be converted into a JSON-like
// map structure.
type UpdateOptsBuilder interface {
	ToLBUpdateMap() (map[string]interface{}, error)
}

// UpdateOpts represents the options for updating an existing load balancer.
type UpdateOpts struct {
	// Optional - new name of the load balancer.
	Name string

	// Optional - the new protocol you want your load balancer to have.
	// See http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/protocols.html
	// for a full list of supported protocols.
	Protocol string

	// Optional - see the HalfClosed field in CreateOpts for more information.
	HalfClosed gophercloud.EnabledState

	// Optional - see the Algorithm field in CreateOpts for more information.
	Algorithm string

	// Optional - see the Port field in CreateOpts for more information.
	Port int

	// Optional - see the Timeout field in CreateOpts for more information.
	Timeout int

	// Optional - see the HTTPSRedirect field in CreateOpts for more information.
	HTTPSRedirect gophercloud.EnabledState
}

// ToLBUpdateMap casts an UpdateOpts struct to a map.
func (opts UpdateOpts) ToLBUpdateMap() (map[string]interface{}, error) {
	lb := make(map[string]interface{})

	if opts.Name != "" {
		lb["name"] = opts.Name
	}
	if opts.Protocol != "" {
		lb["protocol"] = opts.Protocol
	}
	if opts.HalfClosed != nil {
		lb["halfClosed"] = opts.HalfClosed
	}
	if opts.Algorithm != "" {
		lb["algorithm"] = opts.Algorithm
	}
	if opts.Port > 0 {
		lb["port"] = opts.Port
	}
	if opts.Timeout > 0 {
		lb["timeout"] = opts.Timeout
	}
	if opts.HTTPSRedirect != nil {
		lb["httpsRedirect"] = &opts.HTTPSRedirect
	}

	return map[string]interface{}{"loadBalancer": lb}, nil
}

// Update is the operation responsible for asynchronously updating the
// attributes of a specific load balancer. Upon successful validation of the
// request, the service returns a 202 Accepted response, and the load balancer
// enters a PENDING_UPDATE state. A user can poll the load balancer with Get to
// wait for the changes to be applied. When this happens, the load balancer will
// return to an ACTIVE state.
func Update(c *gophercloud.ServiceClient, id int, opts UpdateOptsBuilder) UpdateResult {
	var res UpdateResult

	reqBody, err := opts.ToLBUpdateMap()
	if err != nil {
		res.Err = err
		return res
	}

	_, res.Err = c.Request("PUT", resourceURL(c, id), gophercloud.RequestOpts{
		JSONBody: &reqBody,
		OkCodes:  []int{202},
	})

	return res
}

// ListProtocols is the operation responsible for returning a paginated
// collection of load balancer protocols.
func ListProtocols(client *gophercloud.ServiceClient) pagination.Pager {
	url := protocolsURL(client)
	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
		return ProtocolPage{pagination.SinglePageBase(r)}
	})
}

// ListAlgorithms is the operation responsible for returning a paginated
// collection of load balancer algorithms.
func ListAlgorithms(client *gophercloud.ServiceClient) pagination.Pager {
	url := algorithmsURL(client)
	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
		return AlgorithmPage{pagination.SinglePageBase(r)}
	})
}

// IsLoggingEnabled returns true if the load balancer has connection logging
// enabled and false if not.
func IsLoggingEnabled(client *gophercloud.ServiceClient, id int) (bool, error) {
	var body interface{}

	_, err := client.Request("GET", loggingURL(client, id), gophercloud.RequestOpts{
		JSONResponse: &body,
		OkCodes:      []int{200},
	})
	if err != nil {
		return false, err
	}

	var resp struct {
		CL struct {
			Enabled bool `mapstructure:"enabled"`
		} `mapstructure:"connectionLogging"`
	}

	err = mapstructure.Decode(body, &resp)
	return resp.CL.Enabled, err
}

func toConnLoggingMap(state bool) map[string]map[string]bool {
	return map[string]map[string]bool{
		"connectionLogging": map[string]bool{"enabled": state},
	}
}

// EnableLogging will enable connection logging for a specified load balancer.
func EnableLogging(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
	reqBody := toConnLoggingMap(true)
	var res gophercloud.ErrResult

	_, res.Err = client.Request("PUT", loggingURL(client, id), gophercloud.RequestOpts{
		JSONBody: &reqBody,
		OkCodes:  []int{202},
	})

	return res
}

// DisableLogging will disable connection logging for a specified load balancer.
func DisableLogging(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
	reqBody := toConnLoggingMap(false)
	var res gophercloud.ErrResult

	_, res.Err = client.Request("PUT", loggingURL(client, id), gophercloud.RequestOpts{
		JSONBody: &reqBody,
		OkCodes:  []int{202},
	})

	return res
}

// GetErrorPage will retrieve the current error page for the load balancer.
func GetErrorPage(client *gophercloud.ServiceClient, id int) ErrorPageResult {
	var res ErrorPageResult

	_, res.Err = client.Request("GET", errorPageURL(client, id), gophercloud.RequestOpts{
		JSONResponse: &res.Body,
		OkCodes:      []int{200},
	})

	return res
}

// SetErrorPage will set the HTML of the load balancer's error page to a
// specific value.
func SetErrorPage(client *gophercloud.ServiceClient, id int, html string) ErrorPageResult {
	var res ErrorPageResult

	type stringMap map[string]string
	reqBody := map[string]stringMap{"errorpage": stringMap{"content": html}}

	_, res.Err = client.Request("PUT", errorPageURL(client, id), gophercloud.RequestOpts{
		JSONResponse: &res.Body,
		JSONBody:     &reqBody,
		OkCodes:      []int{200},
	})

	return res
}

// DeleteErrorPage will delete the current error page for the load balancer.
func DeleteErrorPage(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
	var res gophercloud.ErrResult

	_, res.Err = client.Request("DELETE", errorPageURL(client, id), gophercloud.RequestOpts{
		OkCodes: []int{200},
	})

	return res
}

// GetStats will retrieve detailed stats related to the load balancer's usage.
func GetStats(client *gophercloud.ServiceClient, id int) StatsResult {
	var res StatsResult

	_, res.Err = client.Request("GET", statsURL(client, id), gophercloud.RequestOpts{
		JSONResponse: &res.Body,
		OkCodes:      []int{200},
	})

	return res
}

// IsContentCached will check to see whether the specified load balancer caches
// content. When content caching is enabled, recently-accessed files are stored
// on the load balancer for easy retrieval by web clients. Content caching
// improves the performance of high traffic web sites by temporarily storing
// data that was recently accessed. While it's cached, requests for that data
// are served by the load balancer, which in turn reduces load off the back-end
// nodes. The result is improved response times for those requests and less
// load on the web server.
func IsContentCached(client *gophercloud.ServiceClient, id int) (bool, error) {
	var body interface{}

	_, err := client.Request("GET", cacheURL(client, id), gophercloud.RequestOpts{
		JSONResponse: &body,
		OkCodes:      []int{200},
	})
	if err != nil {
		return false, err
	}

	var resp struct {
		CC struct {
			Enabled bool `mapstructure:"enabled"`
		} `mapstructure:"contentCaching"`
	}

	err = mapstructure.Decode(body, &resp)
	return resp.CC.Enabled, err
}

func toCachingMap(state bool) map[string]map[string]bool {
	return map[string]map[string]bool{
		"contentCaching": map[string]bool{"enabled": state},
	}
}

// EnableCaching will enable content-caching for the specified load balancer.
func EnableCaching(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
	reqBody := toCachingMap(true)
	var res gophercloud.ErrResult

	_, res.Err = client.Request("PUT", cacheURL(client, id), gophercloud.RequestOpts{
		JSONBody: &reqBody,
		OkCodes:  []int{202},
	})

	return res
}

// DisableCaching will disable content-caching for the specified load balancer.
func DisableCaching(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
	reqBody := toCachingMap(false)
	var res gophercloud.ErrResult

	_, res.Err = client.Request("PUT", cacheURL(client, id), gophercloud.RequestOpts{
		JSONBody: &reqBody,
		OkCodes:  []int{202},
	})

	return res
}
