package capability

import (
	"bytes"
	"errors"
	"fmt"
	"strings"
)

var (
	// ErrArgumentsRequired is returned if no arguments are giving with a
	// capability that requires arguments
	ErrArgumentsRequired = errors.New("arguments required")
	// ErrArguments is returned if arguments are given with a capabilities that
	// not supports arguments
	ErrArguments = errors.New("arguments not allowed")
	// ErrEmtpyArgument is returned when an empty value is given
	ErrEmtpyArgument = errors.New("empty argument")
	// ErrMultipleArguments multiple argument given to a capabilities that not
	// support it
	ErrMultipleArguments = errors.New("multiple arguments not allowed")
)

// List represents a list of capabilities
type List struct {
	m    map[Capability]*entry
	sort []string
}

type entry struct {
	Name   Capability
	Values []string
}

// NewList returns a new List of capabilities
func NewList() *List {
	return &List{
		m: make(map[Capability]*entry),
	}
}

// IsEmpty returns true if the List is empty
func (l *List) IsEmpty() bool {
	return len(l.sort) == 0
}

// Decode decodes list of capabilities from raw into the list
func (l *List) Decode(raw []byte) error {
	// git 1.x receive pack used to send a leading space on its
	// git-receive-pack capabilities announcement. We just trim space to be
	// tolerant to space changes in different versions.
	raw = bytes.TrimSpace(raw)

	if len(raw) == 0 {
		return nil
	}

	for _, data := range bytes.Split(raw, []byte{' '}) {
		pair := bytes.SplitN(data, []byte{'='}, 2)

		c := Capability(pair[0])
		if len(pair) == 1 {
			if err := l.Add(c); err != nil {
				return err
			}

			continue
		}

		if err := l.Add(c, string(pair[1])); err != nil {
			return err
		}
	}

	return nil
}

// Get returns the values for a capability
func (l *List) Get(capability Capability) []string {
	if _, ok := l.m[capability]; !ok {
		return nil
	}

	return l.m[capability].Values
}

// Set sets a capability removing the previous values
func (l *List) Set(capability Capability, values ...string) error {
	if _, ok := l.m[capability]; ok {
		delete(l.m, capability)
	}

	return l.Add(capability, values...)
}

// Add adds a capability, values are optional
func (l *List) Add(c Capability, values ...string) error {
	if err := l.validate(c, values); err != nil {
		return err
	}

	if !l.Supports(c) {
		l.m[c] = &entry{Name: c}
		l.sort = append(l.sort, c.String())
	}

	if len(values) == 0 {
		return nil
	}

	if known[c] && !multipleArgument[c] && len(l.m[c].Values) > 0 {
		return ErrMultipleArguments
	}

	l.m[c].Values = append(l.m[c].Values, values...)
	return nil
}

func (l *List) validateNoEmptyArgs(values []string) error {
	for _, v := range values {
		if v == "" {
			return ErrEmtpyArgument
		}
	}
	return nil
}

func (l *List) validate(c Capability, values []string) error {
	if !known[c] {
		return l.validateNoEmptyArgs(values)
	}
	if requiresArgument[c] && len(values) == 0 {
		return ErrArgumentsRequired
	}

	if !requiresArgument[c] && len(values) != 0 {
		return ErrArguments
	}

	if !multipleArgument[c] && len(values) > 1 {
		return ErrMultipleArguments
	}
	return l.validateNoEmptyArgs(values)
}

// Supports returns true if capability is present
func (l *List) Supports(capability Capability) bool {
	_, ok := l.m[capability]
	return ok
}

// Delete deletes a capability from the List
func (l *List) Delete(capability Capability) {
	if !l.Supports(capability) {
		return
	}

	delete(l.m, capability)
	for i, c := range l.sort {
		if c != string(capability) {
			continue
		}

		l.sort = append(l.sort[:i], l.sort[i+1:]...)
		return
	}
}

// All returns a slice with all defined capabilities.
func (l *List) All() []Capability {
	var cs []Capability
	for _, key := range l.sort {
		cs = append(cs, Capability(key))
	}

	return cs
}

// String generates the capabilities strings, the capabilities are sorted in
// insertion order
func (l *List) String() string {
	var o []string
	for _, key := range l.sort {
		cap := l.m[Capability(key)]
		if len(cap.Values) == 0 {
			o = append(o, key)
			continue
		}

		for _, value := range cap.Values {
			o = append(o, fmt.Sprintf("%s=%s", key, value))
		}
	}

	return strings.Join(o, " ")
}
