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/sessions"
	"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 *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 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)}
	})
}
