package jpath

import (
	. "github.com/pelletier/go-toml"
)

type nodeFilterFn func(node interface{}) bool
type nodeFn func(node interface{}) interface{}

type QueryResult struct {
	items []interface{}
  positions []Position
}

// TODO: modify after merging with rest of lib
func (r *QueryResult) appendResult(node interface{}) {
  r.items = append(r.items, node)
  switch castNode := node.(type) {
  case *TomlTree:
    r.positions = append(r.positions, castNode.GetPosition(""))
    //r.positions = append(r.positions, castNode.position)
  //case *tomlValue:
    //r.positions = append(r.positions, castNode.position)
  default:
    r.positions = append(r.positions, Position{})
  }
}

func (r *QueryResult) Values() []interface{} {
  return r.items
}

func (r *QueryResult) Positions() []Position {
  return r.positions
}

// runtime context for executing query paths
type queryContext struct {
  result *QueryResult
	filters *map[string]nodeFilterFn
	scripts *map[string]nodeFn
}

// generic path functor interface
type PathFn interface {
	SetNext(next PathFn)
	Call(node interface{}, ctx *queryContext)
}

// encapsulates a query functor chain and script callbacks
type Query struct {
	root    PathFn
	tail    PathFn
	filters *map[string]nodeFilterFn
	scripts *map[string]nodeFn
}

func newQuery() *Query {
	return &Query{
		root:    nil,
		tail:    nil,
		filters: &defaultFilterFunctions,
		scripts: &defaultScriptFunctions,
	}
}

func (q *Query) appendPath(next PathFn) {
	if q.root == nil {
		q.root = next
	} else {
		q.tail.SetNext(next)
	}
	q.tail = next
	next.SetNext(newTerminatingFn()) // init the next functor
}

func Compile(path string) *Query {
	_, flow := lex(path)
	return parse(flow)
}

func (q *Query) Execute(tree *TomlTree) *QueryResult {
  result := &QueryResult {
    items: []interface{}{},
    positions: []Position{},
  }
	if q.root == nil {
    result.appendResult(tree)
	} else {
    ctx := &queryContext{
      result: result,
      filters: q.filters,
      scripts: q.scripts,
    }
    q.root.Call(tree, ctx)
  }
	return result
}

func (q *Query) SetFilter(name string, fn nodeFilterFn) {
	if q.filters == &defaultFilterFunctions {
		// clone the static table
		q.filters = &map[string]nodeFilterFn{}
		for k, v := range defaultFilterFunctions {
			(*q.filters)[k] = v
		}
	}
	(*q.filters)[name] = fn
}

func (q *Query) SetScript(name string, fn nodeFn) {
	if q.scripts == &defaultScriptFunctions {
		// clone the static table
		q.scripts = &map[string]nodeFn{}
		for k, v := range defaultScriptFunctions {
			(*q.scripts)[k] = v
		}
	}
	(*q.scripts)[name] = fn
}

var defaultFilterFunctions = map[string]nodeFilterFn{
	"odd": func(node interface{}) bool {
		if ii, ok := node.(int64); ok {
			return (ii & 1) == 1
		}
		return false
	},
	"even": func(node interface{}) bool {
		if ii, ok := node.(int64); ok {
			return (ii & 1) == 0
		}
		return false
	},
}

var defaultScriptFunctions = map[string]nodeFn{
	"last": func(node interface{}) interface{} {
		if arr, ok := node.([]interface{}); ok {
			return len(arr) - 1
		}
		return nil
	},
}
