// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 pretty implements a simple pretty-printer. It is intended for
// debugging the output of tests.
//
// It follows pointers and produces multi-line output for complex values like
// slices, maps and structs.
package pretty

import (
	"fmt"
	"io"
	"reflect"
	"sort"
	"strings"
	"time"
)

// Indent is the string output at each level of indentation.
var Indent = "    "

// Value returns a value that will print prettily when used as an
// argument for the %v or %s format specifiers.
// With no flags, struct fields and map keys with default values are omitted.
// With the '+' or '#' flags, all values are displayed.
//
// This package does not detect cycles. Attempting to print a Value that
// contains cycles will result in unbounded recursion.
func Value(v interface{}) val { return val{v: v} }

type val struct{ v interface{} }

// Format implements the fmt.Formatter interface.
func (v val) Format(s fmt.State, c rune) {
	if c == 'v' || c == 's' {
		fprint(s, reflect.ValueOf(v.v), state{
			defaults: s.Flag('+') || s.Flag('#'),
		})
	} else {
		fmt.Fprintf(s, "%%!%c(pretty.Val)", c)
	}
}

type state struct {
	level          int
	prefix, suffix string
	defaults       bool
}

const maxLevel = 100

var typeOfTime = reflect.TypeOf(time.Time{})

func fprint(w io.Writer, v reflect.Value, s state) {
	if s.level > maxLevel {
		fmt.Fprintln(w, "pretty: max nested depth exceeded")
		return
	}
	indent := strings.Repeat(Indent, s.level)
	fmt.Fprintf(w, "%s%s", indent, s.prefix)
	if isNil(v) {
		fmt.Fprintf(w, "nil%s", s.suffix)
		return
	}
	if v.Type().Kind() == reflect.Interface {
		v = v.Elem()
	}
	if v.Type() == typeOfTime {
		fmt.Fprintf(w, "%s%s", v.Interface(), s.suffix)
		return
	}
	for v.Type().Kind() == reflect.Ptr {
		fmt.Fprintf(w, "&")
		v = v.Elem()
	}
	switch v.Type().Kind() {
	default:
		fmt.Fprintf(w, "%s%s", short(v), s.suffix)

	case reflect.Array:
		fmt.Fprintf(w, "%s{\n", v.Type())
		for i := 0; i < v.Len(); i++ {
			fprint(w, v.Index(i), state{
				level:    s.level + 1,
				prefix:   "",
				suffix:   ",",
				defaults: s.defaults,
			})
			fmt.Fprintln(w)
		}
		fmt.Fprintf(w, "%s}", indent)

	case reflect.Slice:
		fmt.Fprintf(w, "%s{", v.Type())
		if v.Len() > 0 {
			fmt.Fprintln(w)
			for i := 0; i < v.Len(); i++ {
				fprint(w, v.Index(i), state{
					level:    s.level + 1,
					prefix:   "",
					suffix:   ",",
					defaults: s.defaults,
				})
				fmt.Fprintln(w)
			}
		}
		fmt.Fprintf(w, "%s}%s", indent, s.suffix)

	case reflect.Map:
		fmt.Fprintf(w, "%s{", v.Type())
		if v.Len() > 0 {
			fmt.Fprintln(w)
			keys := v.MapKeys()
			maybeSort(keys, v.Type().Key())
			for _, key := range keys {
				val := v.MapIndex(key)
				if s.defaults || !isDefault(val) {
					fprint(w, val, state{
						level:    s.level + 1,
						prefix:   short(key) + ": ",
						suffix:   ",",
						defaults: s.defaults,
					})
					fmt.Fprintln(w)
				}
			}
		}
		fmt.Fprintf(w, "%s}%s", indent, s.suffix)

	case reflect.Struct:
		t := v.Type()
		fmt.Fprintf(w, "%s{\n", t)
		for i := 0; i < t.NumField(); i++ {
			f := v.Field(i)
			if s.defaults || !isDefault(f) {
				fprint(w, f, state{
					level:    s.level + 1,
					prefix:   t.Field(i).Name + ": ",
					suffix:   ",",
					defaults: s.defaults,
				})
				fmt.Fprintln(w)
			}
		}
		fmt.Fprintf(w, "%s}%s", indent, s.suffix)
	}
}

func isNil(v reflect.Value) bool {
	if !v.IsValid() {
		return true
	}
	switch v.Type().Kind() {
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return v.IsNil()
	default:
		return false
	}
}

func isDefault(v reflect.Value) bool {
	if !v.IsValid() {
		return true
	}
	t := v.Type()
	switch t.Kind() {
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return v.IsNil()
	default:
		if !v.CanInterface() {
			return false
		}
		return t.Comparable() && v.Interface() == reflect.Zero(t).Interface()
	}
}

// short returns a short, one-line string for v.
func short(v reflect.Value) string {
	if !v.IsValid() {
		return "nil"
	}
	if v.Type().Kind() == reflect.String {
		return fmt.Sprintf("%q", v)
	}
	return fmt.Sprintf("%v", v)
}

func indent(w io.Writer, level int) {
	for i := 0; i < level; i++ {
		io.WriteString(w, Indent) // ignore errors
	}
}

func maybeSort(vs []reflect.Value, t reflect.Type) {
	if less := lessFunc(t); less != nil {
		sort.Sort(&sorter{vs, less})
	}
}

// lessFunc returns a function that implements the "<" operator
// for the given type, or nil if the type doesn't support "<" .
func lessFunc(t reflect.Type) func(v1, v2 interface{}) bool {
	switch t.Kind() {
	case reflect.String:
		return func(v1, v2 interface{}) bool { return v1.(string) < v2.(string) }
	case reflect.Int:
		return func(v1, v2 interface{}) bool { return v1.(int) < v2.(int) }
	case reflect.Int8:
		return func(v1, v2 interface{}) bool { return v1.(int8) < v2.(int8) }
	case reflect.Int16:
		return func(v1, v2 interface{}) bool { return v1.(int16) < v2.(int16) }
	case reflect.Int32:
		return func(v1, v2 interface{}) bool { return v1.(int32) < v2.(int32) }
	case reflect.Int64:
		return func(v1, v2 interface{}) bool { return v1.(int64) < v2.(int64) }
	case reflect.Uint:
		return func(v1, v2 interface{}) bool { return v1.(uint) < v2.(uint) }
	case reflect.Uint8:
		return func(v1, v2 interface{}) bool { return v1.(uint8) < v2.(uint8) }
	case reflect.Uint16:
		return func(v1, v2 interface{}) bool { return v1.(uint16) < v2.(uint16) }
	case reflect.Uint32:
		return func(v1, v2 interface{}) bool { return v1.(uint32) < v2.(uint32) }
	case reflect.Uint64:
		return func(v1, v2 interface{}) bool { return v1.(uint64) < v2.(uint64) }
	case reflect.Float32:
		return func(v1, v2 interface{}) bool { return v1.(float32) < v2.(float32) }
	case reflect.Float64:
		return func(v1, v2 interface{}) bool { return v1.(float64) < v2.(float64) }
	default:
		return nil
	}
}

type sorter struct {
	vs   []reflect.Value
	less func(v1, v2 interface{}) bool
}

func (s *sorter) Len() int           { return len(s.vs) }
func (s *sorter) Swap(i, j int)      { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
func (s *sorter) Less(i, j int) bool { return s.less(s.vs[i].Interface(), s.vs[j].Interface()) }
