package acl

import (
	"errors"
	"fmt"

	"github.com/racker/perigee"
	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
	"github.com/rackspace/gophercloud/rackspace/lb/v1"
)

// List is the operation responsible for returning a paginated collection of
// network items that define a load balancer's access list.
func List(client *gophercloud.ServiceClient, lbID int) pagination.Pager {
	url := rootURL(client, lbID)

	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
		return AccessListPage{pagination.SinglePageBase(r)}
	})
}

// CreateOptsBuilder is the interface responsible for generating the JSON
// for a Create operation.
type CreateOptsBuilder interface {
	ToAccessListCreateMap() (map[string]interface{}, error)
}

// CreateOpts is a slice of CreateOpt structs, that allow the user to create
// multiple nodes in a single operation (one node per CreateOpt).
type CreateOpts []CreateOpt

// CreateOpt represents the options to create a single node.
type CreateOpt struct {
	// Required - the IP address or CIDR for item to add to access list.
	Address string

	// Required - the type of the node. Either ALLOW or DENY.
	Type Type
}

// ToAccessListCreateMap converts a slice of options into a map that can be
// used for the JSON.
func (opts CreateOpts) ToAccessListCreateMap() (map[string]interface{}, error) {
	type itemMap map[string]interface{}
	items := []itemMap{}

	for k, v := range opts {
		if v.Address == "" {
			return itemMap{}, fmt.Errorf("Address is a required attribute, none provided for %d CreateOpt element", k)
		}
		if v.Type != ALLOW && v.Type != DENY {
			return itemMap{}, fmt.Errorf("Type must be ALLOW or DENY")
		}

		item := make(itemMap)
		item["address"] = v.Address
		item["type"] = v.Type

		items = append(items, item)
	}

	return itemMap{"accessList": items}, nil
}

// Create is the operation responsible for adding network items to the access
// rules for a particular load balancer. If network items already exist, the
// new item will be appended. A single IP address or subnet range is considered
// unique, and cannot be duplicated.
func Create(client *gophercloud.ServiceClient, loadBalancerID int, opts CreateOptsBuilder) CreateResult {
	var res CreateResult

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

	_, res.Err = perigee.Request("POST", rootURL(client, loadBalancerID), perigee.Options{
		MoreHeaders: client.AuthenticatedHeaders(),
		ReqBody:     &reqBody,
		OkCodes:     []int{202},
	})

	return res
}

// BulkDelete will delete multiple network items from a load balancer's access
// list in a single operation.
func BulkDelete(c *gophercloud.ServiceClient, loadBalancerID int, itemIDs []int) DeleteResult {
	var res DeleteResult

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

	url := rootURL(c, loadBalancerID)
	url += v1.IDSliceToQueryString("id", itemIDs)

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

	return res
}

// Delete will remove a single network item from a load balancer's access list.
func Delete(c *gophercloud.ServiceClient, lbID, itemID int) DeleteResult {
	var res DeleteResult
	_, res.Err = perigee.Request("DELETE", resourceURL(c, lbID, itemID), perigee.Options{
		MoreHeaders: c.AuthenticatedHeaders(),
		OkCodes:     []int{202},
	})
	return res
}

// DeleteAll will delete the entire contents of a load balancer's access list,
// effectively resetting it and allowing all traffic.
func DeleteAll(c *gophercloud.ServiceClient, lbID int) DeleteResult {
	var res DeleteResult
	_, res.Err = perigee.Request("DELETE", rootURL(c, lbID), perigee.Options{
		MoreHeaders: c.AuthenticatedHeaders(),
		OkCodes:     []int{202},
	})
	return res
}
