package webhooks

import (
	"errors"

	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
)

// ErrNoName represents a validation error in which a create or update operation
// has an empty name field.
var ErrNoName = errors.New("Webhook name cannot by empty.")

// List returns all webhooks for a scaling policy.
func List(client *gophercloud.ServiceClient, groupID, policyID string) pagination.Pager {
	url := listURL(client, groupID, policyID)

	createPageFn := func(r pagination.PageResult) pagination.Page {
		return WebhookPage{pagination.SinglePageBase(r)}
	}

	return pagination.NewPager(client, url, createPageFn)
}

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

// CreateOpts is a slice of CreateOpt structs, that allow the user to create
// multiple webhooks in a single operation.
type CreateOpts []CreateOpt

// CreateOpt represents the options to create a webhook.
type CreateOpt struct {
	// Name [required] is a name for the webhook.
	Name string

	// Metadata [optional] is user-provided key-value metadata.
	// Maximum length for keys and values is 256 characters.
	Metadata map[string]string
}

// ToWebhookCreateMap converts a slice of CreateOpt structs into a map for use
// in the request body of a Create operation.
func (opts CreateOpts) ToWebhookCreateMap() ([]map[string]interface{}, error) {
	var webhooks []map[string]interface{}

	for _, o := range opts {
		if o.Name == "" {
			return nil, ErrNoName
		}

		hook := make(map[string]interface{})

		hook["name"] = o.Name

		if o.Metadata != nil {
			hook["metadata"] = o.Metadata
		}

		webhooks = append(webhooks, hook)
	}

	return webhooks, nil
}

// Create requests a new webhook be created and associated with the given group
// and scaling policy.
func Create(client *gophercloud.ServiceClient, groupID, policyID string, opts CreateOptsBuilder) CreateResult {
	var res CreateResult

	reqBody, err := opts.ToWebhookCreateMap()

	if err != nil {
		res.Err = err
		return res
	}

	resp, err := client.Post(createURL(client, groupID, policyID), reqBody, &res.Body, nil)

	if err != nil {
		res.Err = err
		return res
	}

	pr := pagination.PageResultFromParsed(resp, res.Body)
	return CreateResult{pagination.SinglePageBase(pr)}
}

// Get requests the details of a single webhook with the given ID.
func Get(client *gophercloud.ServiceClient, groupID, policyID, webhookID string) GetResult {
	var result GetResult

	_, result.Err = client.Get(getURL(client, groupID, policyID, webhookID), &result.Body, nil)

	return result
}

// UpdateOptsBuilder is the interface responsible for generating the map
// structure for producing JSON for an Update operation.
type UpdateOptsBuilder interface {
	ToWebhookUpdateMap() (map[string]interface{}, error)
}

// UpdateOpts represents the options for updating an existing webhook.
//
// Update operations completely replace the configuration being updated. Empty
// values in the update are accepted and overwrite previously specified
// parameters.
type UpdateOpts struct {
	// Name of the webhook.
	Name string `mapstructure:"name" json:"name"`

	// Metadata associated with the webhook.
	Metadata map[string]string `mapstructure:"metadata" json:"metadata"`
}

// ToWebhookUpdateMap converts an UpdateOpts struct into a map for use as the
// request body in an Update request.
func (opts UpdateOpts) ToWebhookUpdateMap() (map[string]interface{}, error) {
	if opts.Name == "" {
		return nil, ErrNoName
	}

	hook := make(map[string]interface{})

	hook["name"] = opts.Name

	if opts.Metadata != nil {
		hook["metadata"] = opts.Metadata
	}

	return hook, nil
}

// Update requests the configuration of the given webhook be updated.
func Update(client *gophercloud.ServiceClient, groupID, policyID, webhookID string, opts UpdateOptsBuilder) UpdateResult {
	var result UpdateResult

	url := updateURL(client, groupID, policyID, webhookID)
	reqBody, err := opts.ToWebhookUpdateMap()

	if err != nil {
		result.Err = err
		return result
	}

	_, result.Err = client.Put(url, reqBody, nil, &gophercloud.RequestOpts{
		OkCodes: []int{204},
	})

	return result
}

// Delete requests the given webhook be permanently deleted.
func Delete(client *gophercloud.ServiceClient, groupID, policyID, webhookID string) DeleteResult {
	var result DeleteResult

	url := deleteURL(client, groupID, policyID, webhookID)
	_, result.Err = client.Delete(url, &gophercloud.RequestOpts{
		OkCodes: []int{204},
	})

	return result
}
