package api

import (
	"errors"
	"time"
	"unicode"

	"code.google.com/p/go.text/unicode/norm"
	"code.secondbit.org/uuid.hg"
)

var (
	ErrCollectionNotFound  = errors.New("collection not found")
	ErrDomainNotFound      = errors.New("domain not found")
	ErrDomainAlreadyExists = errors.New("domain already attached to a collection")
	ErrItemNotFound        = errors.New("item not found")
	ErrItemAlreadyExists   = errors.New("item already exists")
)

type Datastore interface {
	CreateCollection(c Collection) error
	UpdateCollection(id uuid.ID, change CollectionChange) error
	GetCollectionByDomain(domain string) (Collection, error)
	GetCollectionByID(id uuid.ID) (Collection, error)
	GetCollectionsByUser(id uuid.ID) ([]Collection, error)
	AddDomainToCollection(id uuid.ID, domain string) error
	RemoveDomainFromCollection(id uuid.ID, domain string) error
	GetDomainsByCollection(id uuid.ID) ([]Domain, error)
	DeleteCollection(c Collection) error

	GetItemsByCollectionDomain(domain string, num, offset int) ([]Item, error)
	GetItemsByCollectionID(id uuid.ID, num, offset int) ([]Item, error)
	AddItemToCollection(id uuid.ID, item Item) error
	GetItemByName(collectionID uuid.ID, name string) (Item, error)
	DeleteItem(item Item) error
}

func slugify(in string) string {
	buf := make([]rune, 0, len(in))
	needsDash := false
	for _, r := range norm.NFKD.String(in) {
		if unicode.IsSpace(r) || unicode.IsPunct(r) {
			if needsDash {
				buf = append(buf, '-')
				needsDash = false
			}
		} else {
			buf = append(buf, r)
			needsDash = true
		}
	}
	return string(buf)
}

type Collection struct {
	ID      uuid.ID
	Name    string
	Owner   uuid.ID
	Created time.Time
}

func (c *Collection) ApplyChange(change CollectionChange) {
	if change.Name != nil {
		c.Name = *change.Name
	}
}

type CollectionChange struct {
	Name *string
}

type Domain struct {
	Domain       string
	CollectionID uuid.ID
	Created      time.Time
}

type Item struct {
	Blob         string
	Bucket       string
	CollectionID uuid.ID
	Name         string
}
