// Package managers provides AST managers for the codex package.
package managers

import (
	"github.com/chuckpreslar/codex/nodes"
)

// Accessor is a type def of a function that returns an AttributeNode
type Accessor func(interface{}) *nodes.AttributeNode

// Returns the RelationNode scoped to the Accessor
func (self Accessor) Relation() *nodes.RelationNode {
	return self("").Relation
}

// Returns the name of the RelationNode scoped to the Accessor
func (self Accessor) Name() string {
	return self("").Relation.Name
}

// Returns a pointer to a SelectManager with the initial projections provided.
func (self Accessor) Project(projections ...interface{}) *SelectManager {
	return self.From(self.Relation()).Project(projections...)
}

// Returns a pointer to a SelectManager with the initial filter provided.
func (self Accessor) Where(expr interface{}) *SelectManager {
	return self.From(self.Relation()).Where(expr)
}

// Returns a pointer to a SelectManager with an initial InnerJoinNode.
func (self Accessor) InnerJoin(expr interface{}) *SelectManager {
	return self.From(self.Relation()).InnerJoin(expr)
}

// Returns a pointer to a SelectManager with an initial OuterJoinNode.
func (self Accessor) OuterJoin(expr interface{}) *SelectManager {
	return self.From(self.Relation()).OuterJoin(expr)
}

// Returns a pointer to a SelectManager with an initial Ordering.
func (self Accessor) Order(expr interface{}) *SelectManager {
	return self.From(self.Relation()).Order(expr)
}

// Returns a pointer to a SelectManager with an initial Grouping.
func (self Accessor) Group(groupings ...interface{}) *SelectManager {
	return self.From(self.Relation()).Group(groupings...)
}

// Returns a pointer to a SelectManager with an initial Having.
func (self Accessor) Having(expr interface{}) *SelectManager {
	return self.From(self.Relation()).Having(expr)
}

// Returns a pointer to a SelectManager with for the given RelationNode.
func (self Accessor) From(relation *nodes.RelationNode) *SelectManager {
	return Selection(relation)
}

// Returns a pointer to a InsertManager with initial the values provided.
func (self Accessor) Insert(expr ...interface{}) *InsertManager {
	return Insertion(self.Relation()).Insert(expr...)
}

// Returns a pointer to a UpdateManager with initial the columns provided.
func (self Accessor) Set(expr ...interface{}) *UpdateManager {
	return Modification(self.Relation()).Set(expr...)
}

// Returns a pointer to a DeleteManager with the initial filter provided.
func (self Accessor) Delete(expr interface{}) *DeleteManager {
	return Deletion(self.Relation()).Delete(expr)
}

// Returns string, error generated by calling ToSql on an SelectManager.
func (self Accessor) ToSql() (string, error) {
	return self.From(self.Relation()).ToSql()
}
