package auth

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

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

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

const (
	// SESSIONCOLLECTION defines the collection name for storing session data.
	SESSIONCOLLECTION = "session"
	// SESSIONMODEL defines the name of the session data model.
	SESSIONMODEL = "kontor.admin.session"
)

// FindAll retrieves the list of sessions from the database.
func (m *SessionDAO) FindAll() ([]Session, error) {
	m.Db.Connect()
	var sessions []Session
	err := m.Db.MongoDb.C(SESSIONCOLLECTION).Find(bson.M{"model": SESSIONMODEL}).All(&sessions)
	return sessions, err
}

// FindByID returns a session with given id or returns the error.
func (m *SessionDAO) FindByID(id string) (Session, error) {
	m.Db.Connect()
	var session Session
	err := m.Db.MongoDb.C(SESSIONCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&session)
	return session, err
}

// Insert a session into database.
func (m *SessionDAO) Insert(session Session) error {
	m.Db.Connect()
	session.Model = SESSIONMODEL
	err := m.Db.MongoDb.C(SESSIONCOLLECTION).Insert(&session)
	//log.PrintDebug("Insert: %v, %v\n", session, err)
	return err
}

// Upsert a session into database.
func (m *SessionDAO) Upsert(session Session) (*mgo.ChangeInfo, error) {
	m.Db.Connect()
	session.Model = SESSIONMODEL
	info, err := m.Db.MongoDb.C(SESSIONCOLLECTION).Upsert(bson.M{"_id": session.ID}, &session)
	return info, err
}

// Update an existing session.
func (m *SessionDAO) Update(session Session) error {
	m.Db.Connect()
	err := m.Db.MongoDb.C(SESSIONCOLLECTION).UpdateId(session.ID, &session)
	return err
}

// Delete an existing session.
func (m *SessionDAO) Delete(session Session) error {
	m.Db.Connect()
	err := m.Db.MongoDb.C(SESSIONCOLLECTION).Remove(&session)
	return err
}

// GetSession get a session by given id or create a new one, if nothing was found.
func (m *SessionDAO) GetSession(id string) (*Session, error) {
	m.Db.Connect()
	session, err := m.FindByID(id)
	if err != nil {
		session = Session{ID: bson.ObjectIdHex(id), Username: "", IsAdmin: false}
		m.Insert(session)
	}
	return &session, nil
}
