/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cache

import (
	"errors"
	"github.com/karlseguin/ccache"
	"golang.org/x/net/context"
	"sync"
)

var errNilNode = errors.New("nil node")

type Tree struct {
	Config  *Config
	roots   *ccache.Cache
	filters []Filter
	lock    sync.RWMutex
}

func (t *Tree) AddFilter(fs ...Filter) *Tree {
	t.lock.Lock()
	for _, f := range fs {
		t.filters = append(t.filters, f)
	}
	t.lock.Unlock()
	return t
}

func (t *Tree) Get(ctx context.Context, ops ...Option) (node *Node, err error) {
	var op Option
	if len(ops) > 0 {
		op = ops[0]
	}

	var (
		parent *Node
		i      int
	)

	if !op.NoCache {
		if parent, err = t.getOrCreateRoot(ctx); parent == nil {
			return
		}
		i++
		// parent may be a temp root in concurrent scene
	}

	for ; i < len(t.filters); i++ {
		if op.Level > 0 && op.Level == i {
			break
		}
		if parent, err = t.getOrCreateNode(ctx, i, parent); parent == nil {
			break
		}
	}
	node = parent
	return
}

func (t *Tree) Remove(ctx context.Context) {
	if len(t.filters) == 0 {
		return
	}

	t.roots.Delete(t.filters[0].Name(ctx, nil))
}

func (t *Tree) getOrCreateRoot(ctx context.Context) (node *Node, err error) {
	if len(t.filters) == 0 {
		return
	}

	filter := t.filters[0]
	name := filter.Name(ctx, nil)
	item, err := t.roots.Fetch(name, t.Config.TTL(), func() (interface{}, error) {
		node, err := t.getOrCreateNode(ctx, 0, nil)
		if err != nil {
			return nil, err
		}
		if node == nil {
			return nil, errNilNode
		}
		return node, nil
	})
	switch err {
	case nil:
		node = item.Value().(*Node)
	case errNilNode:
		err = nil
	}
	return
}

func (t *Tree) getOrCreateNode(ctx context.Context, idx int, parent *Node) (node *Node, err error) {
	filter := t.filters[idx]
	name := t.nodeFullName(filter.Name(ctx, parent), parent)

	if parent == nil {
		// new a temp node
		return t.createNode(ctx, idx, name, parent)
	}

	item, err := parent.Childs.Fetch(name, func() (interface{}, error) {
		node, err := t.createNode(ctx, idx, name, parent)
		if err != nil {
			return nil, err
		}
		if node == nil {
			return nil, errNilNode
		}
		return node, nil
	})
	switch err {
	case nil:
		node = item.(*Node)
	case errNilNode:
		err = nil
	}
	return
}

func (t *Tree) nodeFullName(name string, parent *Node) string {
	if parent != nil {
		name = parent.Name + "." + name
	}
	return name
}

func (t *Tree) createNode(ctx context.Context, idx int, name string, parent *Node) (node *Node, err error) {
	node, err = t.filters[idx].Init(ctx, parent)
	if node == nil {
		return
	}
	node.Name = name
	node.Tree = t
	node.Level = idx
	return
}

func NewTree(cfg *Config) *Tree {
	return &Tree{
		Config: cfg,
		roots:  ccache.New(ccache.Configure().MaxSize(cfg.MaxSize())),
	}
}
