package jpath

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

type QueryPath []PathFn

type PathFn func(context interface{}, next QueryPath)

func (path QueryPath) Fn(context interface{}) {
	path[0](context, path[1:])
}

func treeValue(tree *TomlTree, key string) interface{} {
	return tree.GetPath([]string{key})
}

func matchKeyFn(name string) PathFn {
	return func(context interface{}, next QueryPath) {
		if tree, ok := context.(*TomlTree); ok {
			item := treeValue(tree, name)
			if item != nil {
				next.Fn(item)
			}
		}
	}
}

func matchIndexFn(idx int) PathFn {
	return func(context interface{}, next QueryPath) {
		if arr, ok := context.([]interface{}); ok {
			if idx < len(arr) && idx >= 0 {
				next.Fn(arr[idx])
			}
		}
	}
}

func matchSliceFn(start, end, step int) PathFn {
	return func(context interface{}, next QueryPath) {
		if arr, ok := context.([]interface{}); ok {
			// adjust indexes for negative values, reverse ordering
			realStart, realEnd := start, end
			if realStart < 0 {
				realStart = len(arr) + realStart
			}
			if realEnd < 0 {
				realEnd = len(arr) + realEnd
			}
			if realEnd < realStart {
				realEnd, realStart = realStart, realEnd // swap
			}
			// loop and gather
			for idx := realStart; idx < realEnd; idx += step {
				next.Fn(arr[idx])
			}
		}
	}
}

func matchAnyFn() PathFn {
	return func(context interface{}, next QueryPath) {
		if tree, ok := context.(*TomlTree); ok {
			for _, key := range tree.Keys() {
				item := treeValue(tree, key)
				next.Fn(item)
			}
		}
	}
}

func matchUnionFn(union QueryPath) PathFn {
	return func(context interface{}, next QueryPath) {
		for _, fn := range union {
			fn(context, next)
		}
	}
}

func matchRecurseFn() PathFn {
	return func(context interface{}, next QueryPath) {
		if tree, ok := context.(*TomlTree); ok {
			var visit func(tree *TomlTree)
			visit = func(tree *TomlTree) {
				for _, key := range tree.Keys() {
					item := treeValue(tree, key)
					next.Fn(item)
					switch node := item.(type) {
					case *TomlTree:
						visit(node)
					case []*TomlTree:
						for _, subtree := range node {
							visit(subtree)
						}
					}
				}
			}
			visit(tree)
		}
	}
}

func processPath(path QueryPath, context interface{}) []interface{} {
	// terminate the path with a collection funciton
	result := []interface{}{}
	newPath := append(path, func(context interface{}, next QueryPath) {
		result = append(result, context)
	})

	// execute the path
	newPath.Fn(context)
	return result
}
