// Copyright (C) 2016 The Android Open Source Project
//
// Licensed 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 compare

import "fmt"

// Path represents a path from the root of an object hierarchy
type Path []Fragment

// Fragment is an entry in a Path
type Fragment struct {
	// Operation holds the operation occurring at this level in the path.
	Operation interface{}
	// Reference holds the entry in the reference hierarchy to apply the operation to
	Reference interface{}
	// Value holds the equivalent entry in the value hierarchy to apply the the operation to
	Value interface{}
}

// MemberOp is the fragment operation type for member comparisons.
type MemberOp string

// IndexOp is the fragment operation type for array / slice index comparisons.
type IndexOp int

// EntryOp is the fragment operation type for map entry comparisons.
type EntryOp struct {
	Key interface{} // The map key
}

// LengthOp is the fragment operation type for array / slice length comparisons.
type LengthOp string

// TypeOp is the fragment operation type for type comparisons.
type TypeOp string

// NilOp is the fragment operation type for nil-equality comparisons.
type NilOp string

// MissingOp is the fragment operation type for absent entries in arrays,
// slices and maps.
type MissingOp string

const (
	Length = LengthOp("·length")
	Type   = TypeOp("·type")
	Nil    = NilOp("nil")
	Key    = MissingOp("key")
)

func (m MemberOp) Format(f fmt.State, r rune) { fmt.Fprint(f, ".", string(m)) }
func (i IndexOp) Format(f fmt.State, r rune)  { fmt.Fprintf(f, "[%v]", int(i)) }
func (e EntryOp) Format(f fmt.State, r rune)  { fmt.Fprintf(f, "[%v]", e.Key) }

func (p Path) with(op, reference, value interface{}) Path {
	r := make(Path, len(p)+1)
	copy(r, p)
	r[len(p)] = Fragment{op, reference, value}
	return r
}

// Member returns a new Path with a member access fragment appended.
func (p Path) Member(name string, reference, value interface{}) Path {
	return p.with(MemberOp(name), reference, value)
}

// Length returns a new Path with a length query fragment appended.
func (p Path) Length(reference, value interface{}) Path { return p.with(Length, reference, value) }

// Type returns a new Path with a type query fragment appended.
func (p Path) Type(reference, value interface{}) Path { return p.with(Type, reference, value) }

// Nil returns a new Path with a nil query fragment appended.
func (p Path) Nil(reference, value interface{}) Path { return p.with(Nil, reference, value) }

// Missing returns a new Path with a missing value fragment appended.
func (p Path) Missing(reference, value interface{}) Path { return p.with(Key, reference, value) }

// Index returns a new Path with an array/slice index fragment appended.
func (p Path) Index(i int, reference, value interface{}) Path {
	return p.with(IndexOp(i), reference, value)
}

// Entry returns a new Path with a map entry fragment appended.
func (p Path) Entry(key, reference, value interface{}) Path {
	return p.with(EntryOp{key}, reference, value)
}

// Diff returns a new Path with a terminal diff fragment appended.
func (p Path) Diff(reference, value interface{}) Path { return p.with(nil, reference, value) }

func (p Path) Format(f fmt.State, r rune) {
	if len(p) == 0 {
		return
	}
	last := p[len(p)-1]
	remains := p[:len(p)-1]
	if last.Operation != nil {
		fmt.Fprint(f, last.Operation, " ")
	}
	fmt.Fprint(f, "«", last.Reference, "» != «", last.Value, "»")
	if len(remains) > 0 {
		fmt.Fprint(f, " for v")
		for _, e := range remains {
			fmt.Fprint(f, e.Operation)
		}
	}
}
