package lbs

import (
	"errors"

	"github.com/racker/perigee"

	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
	"github.com/rackspace/gophercloud/rackspace/lb/v1"
	"github.com/rackspace/gophercloud/rackspace/lb/v1/nodes"
	"github.com/rackspace/gophercloud/rackspace/lb/v1/vips"
)

// 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}}
	})
}

type enabledState *bool

// Convenience vars to help setting enabled state.
var (
	iTrue  = true
	iFalse = false

	Enabled  enabledState = &iTrue
	Disabled enabledState = &iFalse
)

// 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 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 string

	// 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 *ConnectionThrottle

	// Optional -
	//HealthMonitor string

	// 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 *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 enabledState
}

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

// 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 != "" {
	// 	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 != "" {
	// 	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, a 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 = perigee.Request("POST", rootURL(c), perigee.Options{
		MoreHeaders: c.AuthenticatedHeaders(),
		ReqBody:     &reqBody,
		Results:     &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 = perigee.Request("GET", resourceURL(c, id), perigee.Options{
		MoreHeaders: c.AuthenticatedHeaders(),
		Results:     &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 are
// 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 += v1.IDSliceToQueryString("id", ids)

	_, res.Err = perigee.Request("DELETE", url, perigee.Options{
		MoreHeaders: c.AuthenticatedHeaders(),
		OkCodes:     []int{202},
	})

	return res
}

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

	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
		MoreHeaders: c.AuthenticatedHeaders(),
		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 represent 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 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 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 = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
		MoreHeaders: c.AuthenticatedHeaders(),
		ReqBody:     &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)}
	})
}
