// Copyright 2014 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.

// This file implements writing of types. The functionality is lifted
// directly from go/types, but now contains various modifications for
// nicer output.
//
// TODO(gri) back-port once we have a fixed interface and once the
// go/types API is not frozen anymore for the 1.3 release; and remove
// this implementation if possible.

package main

import "golang.org/x/tools/go/types"

func (p *printer) writeType(this *types.Package, typ types.Type) {
	p.writeTypeInternal(this, typ, make([]types.Type, 8))
}

// From go/types - leave for now to ease back-porting this code.
const GcCompatibilityMode = false

func (p *printer) writeTypeInternal(this *types.Package, typ types.Type, visited []types.Type) {
	// Theoretically, this is a quadratic lookup algorithm, but in
	// practice deeply nested composite types with unnamed component
	// types are uncommon. This code is likely more efficient than
	// using a map.
	for _, t := range visited {
		if t == typ {
			p.printf("○%T", typ) // cycle to typ
			return
		}
	}
	visited = append(visited, typ)

	switch t := typ.(type) {
	case nil:
		p.print("<nil>")

	case *types.Basic:
		if t.Kind() == types.UnsafePointer {
			p.print("unsafe.")
		}
		if GcCompatibilityMode {
			// forget the alias names
			switch t.Kind() {
			case types.Byte:
				t = types.Typ[types.Uint8]
			case types.Rune:
				t = types.Typ[types.Int32]
			}
		}
		p.print(t.Name())

	case *types.Array:
		p.printf("[%d]", t.Len())
		p.writeTypeInternal(this, t.Elem(), visited)

	case *types.Slice:
		p.print("[]")
		p.writeTypeInternal(this, t.Elem(), visited)

	case *types.Struct:
		n := t.NumFields()
		if n == 0 {
			p.print("struct{}")
			return
		}

		p.print("struct {\n")
		p.indent++
		for i := 0; i < n; i++ {
			f := t.Field(i)
			if !f.Anonymous() {
				p.printf("%s ", f.Name())
			}
			p.writeTypeInternal(this, f.Type(), visited)
			if tag := t.Tag(i); tag != "" {
				p.printf(" %q", tag)
			}
			p.print("\n")
		}
		p.indent--
		p.print("}")

	case *types.Pointer:
		p.print("*")
		p.writeTypeInternal(this, t.Elem(), visited)

	case *types.Tuple:
		p.writeTuple(this, t, false, visited)

	case *types.Signature:
		p.print("func")
		p.writeSignatureInternal(this, t, visited)

	case *types.Interface:
		// We write the source-level methods and embedded types rather
		// than the actual method set since resolved method signatures
		// may have non-printable cycles if parameters have anonymous
		// interface types that (directly or indirectly) embed the
		// current interface. For instance, consider the result type
		// of m:
		//
		//     type T interface{
		//         m() interface{ T }
		//     }
		//
		n := t.NumMethods()
		if n == 0 {
			p.print("interface{}")
			return
		}

		p.print("interface {\n")
		p.indent++
		if GcCompatibilityMode {
			// print flattened interface
			// (useful to compare against gc-generated interfaces)
			for i := 0; i < n; i++ {
				m := t.Method(i)
				p.print(m.Name())
				p.writeSignatureInternal(this, m.Type().(*types.Signature), visited)
				p.print("\n")
			}
		} else {
			// print explicit interface methods and embedded types
			for i, n := 0, t.NumExplicitMethods(); i < n; i++ {
				m := t.ExplicitMethod(i)
				p.print(m.Name())
				p.writeSignatureInternal(this, m.Type().(*types.Signature), visited)
				p.print("\n")
			}
			for i, n := 0, t.NumEmbeddeds(); i < n; i++ {
				typ := t.Embedded(i)
				p.writeTypeInternal(this, typ, visited)
				p.print("\n")
			}
		}
		p.indent--
		p.print("}")

	case *types.Map:
		p.print("map[")
		p.writeTypeInternal(this, t.Key(), visited)
		p.print("]")
		p.writeTypeInternal(this, t.Elem(), visited)

	case *types.Chan:
		var s string
		var parens bool
		switch t.Dir() {
		case types.SendRecv:
			s = "chan "
			// chan (<-chan T) requires parentheses
			if c, _ := t.Elem().(*types.Chan); c != nil && c.Dir() == types.RecvOnly {
				parens = true
			}
		case types.SendOnly:
			s = "chan<- "
		case types.RecvOnly:
			s = "<-chan "
		default:
			panic("unreachable")
		}
		p.print(s)
		if parens {
			p.print("(")
		}
		p.writeTypeInternal(this, t.Elem(), visited)
		if parens {
			p.print(")")
		}

	case *types.Named:
		s := "<Named w/o object>"
		if obj := t.Obj(); obj != nil {
			if pkg := obj.Pkg(); pkg != nil {
				if pkg != this {
					p.print(pkg.Path())
					p.print(".")
				}
				// TODO(gri): function-local named types should be displayed
				// differently from named types at package level to avoid
				// ambiguity.
			}
			s = obj.Name()
		}
		p.print(s)

	default:
		// For externally defined implementations of Type.
		p.print(t.String())
	}
}

func (p *printer) writeTuple(this *types.Package, tup *types.Tuple, variadic bool, visited []types.Type) {
	p.print("(")
	for i, n := 0, tup.Len(); i < n; i++ {
		if i > 0 {
			p.print(", ")
		}
		v := tup.At(i)
		if name := v.Name(); name != "" {
			p.print(name)
			p.print(" ")
		}
		typ := v.Type()
		if variadic && i == n-1 {
			p.print("...")
			typ = typ.(*types.Slice).Elem()
		}
		p.writeTypeInternal(this, typ, visited)
	}
	p.print(")")
}

func (p *printer) writeSignature(this *types.Package, sig *types.Signature) {
	p.writeSignatureInternal(this, sig, make([]types.Type, 8))
}

func (p *printer) writeSignatureInternal(this *types.Package, sig *types.Signature, visited []types.Type) {
	p.writeTuple(this, sig.Params(), sig.Variadic(), visited)

	res := sig.Results()
	n := res.Len()
	if n == 0 {
		// no result
		return
	}

	p.print(" ")
	if n == 1 && res.At(0).Name() == "" {
		// single unnamed result
		p.writeTypeInternal(this, res.At(0).Type(), visited)
		return
	}

	// multiple or named result(s)
	p.writeTuple(this, res, false, visited)
}
