// Copyright 2012 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 typechecking of conversions.

package types

import (
	"go/ast"

	"code.google.com/p/go.exp/go/exact"
)

// conversion typechecks the type conversion conv to type typ. iota is the current
// value of iota or -1 if iota doesn't have a value in the current context. The result
// of the conversion is returned via x. If the conversion has type errors, the returned
// x is marked as invalid (x.mode == invalid).
//
func (check *checker) conversion(x *operand, conv *ast.CallExpr, typ Type, iota int) {
	// all conversions have one argument
	if len(conv.Args) != 1 {
		check.invalidOp(conv.Pos(), "%s conversion requires exactly one argument", conv)
		goto Error
	}

	// evaluate argument
	check.expr(x, conv.Args[0], nil, iota)
	if x.mode == invalid {
		goto Error
	}

	if x.mode == constant && isConstType(typ) {
		// constant conversion
		typ := typ.Underlying().(*Basic)
		// For now just implement string(x) where x is an integer,
		// as a temporary work-around for issue 4982, which is a
		// common issue.
		if typ.kind == String {
			switch {
			case x.isInteger():
				codepoint := int64(-1)
				if i, ok := exact.Int64Val(x.val); ok {
					codepoint = i
				}
				// If codepoint < 0 the absolute value is too large (or unknown) for
				// conversion. This is the same as converting any other out-of-range
				// value - let string(codepoint) do the work.
				x.val = exact.MakeString(string(codepoint))
			case isString(x.typ):
				// nothing to do
			default:
				goto ErrorMsg
			}
		}
		// TODO(gri) verify the remaining conversions.
	} else {
		// non-constant conversion
		if !x.isConvertible(check.ctxt, typ) {
			goto ErrorMsg
		}
		x.mode = value
	}

	// the conversion argument types are final; for now we just use x.typ
	// TODO(gri) Fix this. For untyped constants, the type should be typ.
	check.updateExprType(x.expr, x.typ, true)

	check.conversions[conv] = true // for cap/len checking
	x.expr = conv
	x.typ = typ
	return

ErrorMsg:
	check.invalidOp(conv.Pos(), "cannot convert %s to %s", x, typ)
Error:
	x.mode = invalid
	x.expr = conv
}

func (x *operand) isConvertible(ctxt *Context, T Type) bool {
	// "x is assignable to T"
	if x.isAssignable(ctxt, T) {
		return true
	}

	// "x's type and T have identical underlying types"
	V := x.typ
	Vu := V.Underlying()
	Tu := T.Underlying()
	if IsIdentical(Vu, Tu) {
		return true
	}

	// "x's type and T are unnamed pointer types and their pointer base types have identical underlying types"
	if V, ok := V.(*Pointer); ok {
		if T, ok := T.(*Pointer); ok {
			if IsIdentical(V.base.Underlying(), T.base.Underlying()) {
				return true
			}
		}
	}

	// "x's type and T are both integer or floating point types"
	if (isInteger(V) || isFloat(V)) && (isInteger(T) || isFloat(T)) {
		return true
	}

	// "x's type and T are both complex types"
	if isComplex(V) && isComplex(T) {
		return true
	}

	// "x is an integer or a slice of bytes or runes and T is a string type"
	if (isInteger(V) || isBytesOrRunes(Vu)) && isString(T) {
		return true
	}

	// "x is a string and T is a slice of bytes or runes"
	if isString(V) && isBytesOrRunes(Tu) {
		return true
	}

	// package unsafe:
	// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
	if (isPointer(Vu) || isUintptr(Vu)) && isUnsafePointer(T) {
		return true
	}
	// "and vice versa"
	if isUnsafePointer(V) && (isPointer(Tu) || isUintptr(Tu)) {
		return true
	}

	return false
}

func isUintptr(typ Type) bool {
	t, ok := typ.(*Basic)
	return ok && t.kind == Uintptr
}

func isUnsafePointer(typ Type) bool {
	t, ok := typ.(*Basic)
	return ok && t.kind == UnsafePointer
}

func isPointer(typ Type) bool {
	_, ok := typ.(*Pointer)
	return ok
}

func isBytesOrRunes(typ Type) bool {
	if s, ok := typ.(*Slice); ok {
		t, ok := s.elt.Underlying().(*Basic)
		return ok && (t.kind == Byte || t.kind == Rune)
	}
	return false
}
