package library

import (
	"gitlab.thpeetz.de/kontor/kontor-go/pkg/dao"

	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

// AuthorDAO extends the type BaseDAO.
type AuthorDAO struct {
	Db dao.BaseDAO
}

const (
	// AUTHORCOLLECTION defines the collection name for storing authors.
	AUTHORCOLLECTION = "author"
	// AUTHORMODEL defines the name of the author data model.
	AUTHORMODEL = "kontor.library.author"
)

// FindAll retrieves the list of authors from the database.
func (m *AuthorDAO) FindAll() ([]Author, error) {
	m.Db.Connect()
	var authors []Author
	err := m.Db.MongoDb.C(AUTHORCOLLECTION).Find(bson.M{"model": AUTHORMODEL}).All(&authors)
	return authors, err
}

// FindByID returns an author with given id or returns the error.
func (m *AuthorDAO) FindByID(id string) (Author, error) {
	m.Db.Connect()
	var author Author
	err := m.Db.MongoDb.C(AUTHORCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&author)
	return author, err
}

// FindByName returns an author with given name or returns the error.
func (m *AuthorDAO) FindByName(name string) (Author, error) {
	m.Db.Connect()
	var author Author
	err := m.Db.MongoDb.C(AUTHORCOLLECTION).Find(bson.M{"name": name, "model": AUTHORMODEL}).One(&author)
	return author, err
}

// Insert a author into database.
func (m *AuthorDAO) Insert(author Author) error {
	m.Db.Connect()
	author.Model = AUTHORMODEL
	err := m.Db.MongoDb.C(AUTHORCOLLECTION).Insert(&author)
	return err
}

// Upsert a author into database.
func (m *AuthorDAO) Upsert(author Author) (*mgo.ChangeInfo, error) {
	m.Db.Connect()
	author.Model = AUTHORMODEL
	info, err := m.Db.MongoDb.C(AUTHORCOLLECTION).Upsert(bson.M{"name": author.Name}, &author)
	return info, err
}

// Delete an existing author.
func (m *AuthorDAO) Delete(author Author) error {
	m.Db.Connect()
	err := m.Db.MongoDb.C(AUTHORCOLLECTION).Remove(&author)
	return err
}

// Update an existing author.
func (m *AuthorDAO) Update(author Author) error {
	m.Db.Connect()
	err := m.Db.MongoDb.C(AUTHORCOLLECTION).UpdateId(author.ID, &author)
	return err
}
