// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// trie implements persistent Patricia trie maps.
//
// Each Map is effectively a map from uint64 to interface{}. Patricia tries are
// a form of radix tree that are particularly appropriate when many maps will be
// created, merged together and large amounts of sharing are expected (e.g.
// environment abstract domains in program analysis).
//
// This implementation closely follows the paper:
//
//	C. Okasaki and A. Gill, “Fast mergeable integer maps,” in ACM SIGPLAN
//	Workshop on ML, September 1998, pp. 77–86.
//
// Each Map is immutable and can be read from concurrently. The map does not
// guarantee that the value pointed to by the interface{} value is not updated
// concurrently.
//
// These Maps are optimized for situations where there will be many maps created at
// with a high degree of sharing and combining of maps together. If you do not expect,
// significant amount of sharing, the builtin map[T]U is much better choice!
//
// Each Map is created by a Builder. Each Builder has a unique Scope and each node is
// created within this scope. Maps x and y are == if they contains the same
// (key,value) mappings and have equal scopes.
//
// Internally these are big endian Patricia trie nodes, and the keys are sorted.
package trie

import (
	"fmt"
	"strings"
)

// Map is effectively a finite mapping from uint64 keys to interface{} values.
// Maps are immutable and can be read from concurrently.
//
// Notes on concurrency:
//   - A Map value itself is an interface and assignments to a Map value can race.
//   - Map does not guarantee that the value pointed to by the interface{} value
//     is not updated concurrently.
type Map struct {
	s Scope
	n node
}

func (m Map) Scope() Scope {
	return m.s
}
func (m Map) Size() int {
	if m.n == nil {
		return 0
	}
	return m.n.size()
}
func (m Map) Lookup(k uint64) (interface{}, bool) {
	if m.n != nil {
		if leaf := m.n.find(key(k)); leaf != nil {
			return leaf.v, true
		}
	}
	return nil, false
}

// Converts the map into a {<key>: <value>[, ...]} string. This uses the default
// %s string conversion for <value>.
func (m Map) String() string {
	var kvs []string
	m.Range(func(u uint64, i interface{}) bool {
		kvs = append(kvs, fmt.Sprintf("%d: %s", u, i))
		return true
	})
	return fmt.Sprintf("{%s}", strings.Join(kvs, ", "))
}

// Range over the leaf (key, value) pairs in the map in order and
// applies cb(key, value) to each. Stops early if cb returns false.
// Returns true if all elements were visited without stopping early.
func (m Map) Range(cb func(uint64, interface{}) bool) bool {
	if m.n != nil {
		return m.n.visit(cb)
	}
	return true
}

// DeepEqual returns true if m and other contain the same (k, v) mappings
// [regardless of Scope].
//
// Equivalently m.DeepEqual(other) <=> reflect.DeepEqual(Elems(m), Elems(other))
func (m Map) DeepEqual(other Map) bool {
	if m.Scope() == other.Scope() {
		return m.n == other.n
	}
	if (m.n == nil) || (other.n == nil) {
		return m.Size() == 0 && other.Size() == 0
	}
	return m.n.deepEqual(other.n)
}

// Elems are the (k,v) elements in the Map as a map[uint64]interface{}
func Elems(m Map) map[uint64]interface{} {
	dest := make(map[uint64]interface{}, m.Size())
	m.Range(func(k uint64, v interface{}) bool {
		dest[k] = v
		return true
	})
	return dest
}

// node is an internal node within a trie map.
// A node is either empty, a leaf or a branch.
type node interface {
	size() int

	// visit the leaves (key, value) pairs in the map in order and
	// applies cb(key, value) to each. Stops early if cb returns false.
	// Returns true if all elements were visited without stopping early.
	visit(cb func(uint64, interface{}) bool) bool

	// Two nodes contain the same elements regardless of scope.
	deepEqual(node) bool

	// find the leaf for the given key value or nil if it is not present.
	find(k key) *leaf

	// implementations must implement this.
	nodeImpl()
}

// empty represents the empty map within a scope.
//
// The current builder ensure
type empty struct {
	s Scope
}

// leaf represents a single <key, value> pair.
type leaf struct {
	k key
	v interface{}
}

// branch represents a tree node within the Patricia trie.
//
// All keys within the branch match a `prefix` of the key
// up to a `branching` bit, and the left and right nodes
// contain keys that disagree on the bit at the `branching` bit.
type branch struct {
	sz        int    // size. cached for O(1) lookup
	prefix    prefix // == mask(p0, branching) for some p0
	branching bitpos

	// Invariants:
	// - neither is nil.
	// - neither is *empty.
	// - all keys in left are <= p.
	// - all keys in right are > p.
	left, right node
}

// all of these types are Maps.
var _ node = &empty{}
var _ node = &leaf{}
var _ node = &branch{}

func (*empty) nodeImpl()  {}
func (*leaf) nodeImpl()   {}
func (*branch) nodeImpl() {}

func (*empty) find(k key) *leaf { return nil }
func (l *leaf) find(k key) *leaf {
	if k == l.k {
		return l
	}
	return nil
}
func (br *branch) find(k key) *leaf {
	kp := prefix(k)
	if !matchPrefix(kp, br.prefix, br.branching) {
		return nil
	}
	if zeroBit(kp, br.branching) {
		return br.left.find(k)
	}
	return br.right.find(k)
}

func (*empty) size() int     { return 0 }
func (*leaf) size() int      { return 1 }
func (br *branch) size() int { return br.sz }

func (*empty) deepEqual(m node) bool {
	_, ok := m.(*empty)
	return ok
}
func (l *leaf) deepEqual(m node) bool {
	if m, ok := m.(*leaf); ok {
		return m == l || (l.k == m.k && l.v == m.v)
	}
	return false
}

func (br *branch) deepEqual(m node) bool {
	if m, ok := m.(*branch); ok {
		if br == m {
			return true
		}
		return br.sz == m.sz && br.branching == m.branching && br.prefix == m.prefix &&
			br.left.deepEqual(m.left) && br.right.deepEqual(m.right)
	}
	// if m is not a branch, m contains 0 or 1 elem.
	// br contains at least 2 keys that disagree on a prefix.
	return false
}

func (*empty) visit(cb func(uint64, interface{}) bool) bool {
	return true
}
func (l *leaf) visit(cb func(uint64, interface{}) bool) bool {
	return cb(uint64(l.k), l.v)
}
func (br *branch) visit(cb func(uint64, interface{}) bool) bool {
	if !br.left.visit(cb) {
		return false
	}
	return br.right.visit(cb)
}
