// Copyright 2017, 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.md file.

package cmpopts

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/google/go-cmp/cmp"
)

// filterField returns a new Option where opt is only evaluated on paths that
// include a specific exported field on a single struct type.
// The struct type is specified by passing in a value of that type.
//
// The name may be a dot-delimited string (e.g., "Foo.Bar") to select a
// specific sub-field that is embedded or nested within the parent struct.
func filterField(typ interface{}, name string, opt cmp.Option) cmp.Option {
	// TODO: This is currently unexported over concerns of how helper filters
	// can be composed together easily.
	// TODO: Add tests for FilterField.

	sf := newStructFilter(typ, name)
	return cmp.FilterPath(sf.filter, opt)
}

type structFilter struct {
	t  reflect.Type // The root struct type to match on
	ft fieldTree    // Tree of fields to match on
}

func newStructFilter(typ interface{}, names ...string) structFilter {
	// TODO: Perhaps allow * as a special identifier to allow ignoring any
	// number of path steps until the next field match?
	// This could be useful when a concrete struct gets transformed into
	// an anonymous struct where it is not possible to specify that by type,
	// but the transformer happens to provide guarantees about the names of
	// the transformed fields.

	t := reflect.TypeOf(typ)
	if t == nil || t.Kind() != reflect.Struct {
		panic(fmt.Sprintf("%T must be a struct", typ))
	}
	var ft fieldTree
	for _, name := range names {
		cname, err := canonicalName(t, name)
		if err != nil {
			panic(fmt.Sprintf("%s: %v", strings.Join(cname, "."), err))
		}
		ft.insert(cname)
	}
	return structFilter{t, ft}
}

func (sf structFilter) filter(p cmp.Path) bool {
	for i, ps := range p {
		if ps.Type().AssignableTo(sf.t) && sf.ft.matchPrefix(p[i+1:]) {
			return true
		}
	}
	return false
}

// fieldTree represents a set of dot-separated identifiers.
//
// For example, inserting the following selectors:
//	Foo
//	Foo.Bar.Baz
//	Foo.Buzz
//	Nuka.Cola.Quantum
//
// Results in a tree of the form:
//	{sub: {
//		"Foo": {ok: true, sub: {
//			"Bar": {sub: {
//				"Baz": {ok: true},
//			}},
//			"Buzz": {ok: true},
//		}},
//		"Nuka": {sub: {
//			"Cola": {sub: {
//				"Quantum": {ok: true},
//			}},
//		}},
//	}}
type fieldTree struct {
	ok  bool                 // Whether this is a specified node
	sub map[string]fieldTree // The sub-tree of fields under this node
}

// insert inserts a sequence of field accesses into the tree.
func (ft *fieldTree) insert(cname []string) {
	if ft.sub == nil {
		ft.sub = make(map[string]fieldTree)
	}
	if len(cname) == 0 {
		ft.ok = true
		return
	}
	sub := ft.sub[cname[0]]
	sub.insert(cname[1:])
	ft.sub[cname[0]] = sub
}

// matchPrefix reports whether any selector in the fieldTree matches
// the start of path p.
func (ft fieldTree) matchPrefix(p cmp.Path) bool {
	for _, ps := range p {
		switch ps := ps.(type) {
		case cmp.StructField:
			ft = ft.sub[ps.Name()]
			if ft.ok {
				return true
			}
			if len(ft.sub) == 0 {
				return false
			}
		case cmp.Indirect:
		default:
			return false
		}
	}
	return false
}

// canonicalName returns a list of identifiers where any struct field access
// through an embedded field is expanded to include the names of the embedded
// types themselves.
//
// For example, suppose field "Foo" is not directly in the parent struct,
// but actually from an embedded struct of type "Bar". Then, the canonical name
// of "Foo" is actually "Bar.Foo".
//
// Suppose field "Foo" is not directly in the parent struct, but actually
// a field in two different embedded structs of types "Bar" and "Baz".
// Then the selector "Foo" causes a panic since it is ambiguous which one it
// refers to. The user must specify either "Bar.Foo" or "Baz.Foo".
func canonicalName(t reflect.Type, sel string) ([]string, error) {
	var name string
	sel = strings.TrimPrefix(sel, ".")
	if sel == "" {
		return nil, fmt.Errorf("name must not be empty")
	}
	if i := strings.IndexByte(sel, '.'); i < 0 {
		name, sel = sel, ""
	} else {
		name, sel = sel[:i], sel[i:]
	}

	// Type must be a struct or pointer to struct.
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	if t.Kind() != reflect.Struct {
		return nil, fmt.Errorf("%v must be a struct", t)
	}

	// Find the canonical name for this current field name.
	// If the field exists in an embedded struct, then it will be expanded.
	if !isExported(name) {
		// Disallow unexported fields:
		//	* To discourage people from actually touching unexported fields
		//	* FieldByName is buggy (https://golang.org/issue/4876)
		return []string{name}, fmt.Errorf("name must be exported")
	}
	sf, ok := t.FieldByName(name)
	if !ok {
		return []string{name}, fmt.Errorf("does not exist")
	}
	var ss []string
	for i := range sf.Index {
		ss = append(ss, t.FieldByIndex(sf.Index[:i+1]).Name)
	}
	if sel == "" {
		return ss, nil
	}
	ssPost, err := canonicalName(sf.Type, sel)
	return append(ss, ssPost...), err
}
