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

// Binary package import.
// Based loosely on x/tools/go/importer.

package gc

import (
	"bufio"
	"cmd/compile/internal/big"
	"encoding/binary"
	"fmt"
)

// The overall structure of Import is symmetric to Export: For each
// export method in bexport.go there is a matching and symmetric method
// in bimport.go. Changing the export format requires making symmetric
// changes to bimport.go and bexport.go.

// Import populates importpkg from the serialized package data.
func Import(in *bufio.Reader) {
	p := importer{in: in}
	p.buf = p.bufarray[:]

	// read low-level encoding format
	switch format := p.byte(); format {
	case 'c':
		// compact format - nothing to do
	case 'd':
		p.debugFormat = true
	default:
		Fatalf("importer: invalid encoding format in export data: got %q; want 'c' or 'd'", format)
	}

	// --- generic export data ---

	if v := p.string(); v != exportVersion {
		Fatalf("importer: unknown export data version: %s", v)
	}

	// populate typList with predeclared "known" types
	p.typList = append(p.typList, predeclared()...)

	// read package data
	p.pkg()
	if p.pkgList[0] != importpkg {
		Fatalf("importer: imported package not found in pkgList[0]")
	}

	// read compiler-specific flags
	importpkg.Safe = p.string() == "safe"

	// defer some type-checking until all types are read in completely
	// (parser.go:import_package)
	tcok := typecheckok
	typecheckok = true
	defercheckwidth()

	// read consts
	for i := p.int(); i > 0; i-- {
		sym := p.localname()
		typ := p.typ()
		val := p.value(typ)
		importconst(sym, idealType(typ), nodlit(val))
	}

	// read vars
	for i := p.int(); i > 0; i-- {
		sym := p.localname()
		typ := p.typ()
		importvar(sym, typ)
	}

	// read funcs
	for i := p.int(); i > 0; i-- {
		// parser.go:hidden_fndcl
		sym := p.localname()
		params := p.paramList()
		result := p.paramList()
		inl := p.int()

		sig := functype(nil, params, result)
		importsym(sym, ONAME)
		if sym.Def != nil && sym.Def.Op == ONAME && !Eqtype(sig, sym.Def.Type) {
			Fatalf("importer: inconsistent definition for func %v during import\n\t%v\n\t%v", sym, sym.Def.Type, sig)
		}

		n := newfuncname(sym)
		n.Type = sig
		declare(n, PFUNC)
		funchdr(n)

		// parser.go:hidden_import
		n.Func.Inl.Set(nil)
		if inl >= 0 {
			if inl != len(p.inlined) {
				panic(fmt.Sprintf("inlined body list inconsistent: %d != %d", inl, len(p.inlined)))
			}
			p.inlined = append(p.inlined, n.Func)
		}
		funcbody(n)
		importlist = append(importlist, n) // TODO(gri) do this only if body is inlineable?
	}

	// read types
	for i := p.int(); i > 0; i-- {
		// name is parsed as part of named type
		p.typ()
	}

	// --- compiler-specific export data ---

	// read inlined functions bodies
	n := p.int()
	for i := 0; i < n; i++ {
		body := p.block()
		const hookup = false // TODO(gri) enable and remove this condition
		if hookup {
			p.inlined[i].Inl.Set(body)
		}
	}

	// --- end of export data ---

	typecheckok = tcok
	resumecheckwidth()

	testdclstack() // debugging only
}

func idealType(typ *Type) *Type {
	if typ.IsUntyped() {
		// canonicalize ideal types
		typ = Types[TIDEAL]
	}
	return typ
}

type importer struct {
	in       *bufio.Reader
	buf      []byte   // for reading strings
	bufarray [64]byte // initial underlying array for buf, large enough to avoid allocation when compiling std lib
	pkgList  []*Pkg
	typList  []*Type
	inlined  []*Func

	debugFormat bool
	read        int // bytes read
}

func (p *importer) pkg() *Pkg {
	// if the package was seen before, i is its index (>= 0)
	i := p.tagOrIndex()
	if i >= 0 {
		return p.pkgList[i]
	}

	// otherwise, i is the package tag (< 0)
	if i != packageTag {
		Fatalf("importer: expected package tag, found tag = %d", i)
	}

	// read package data
	name := p.string()
	path := p.string()

	// we should never see an empty package name
	if name == "" {
		Fatalf("importer: empty package name in import")
	}

	// we should never see a bad import path
	if isbadimport(path) {
		Fatalf("importer: bad path in import: %q", path)
	}

	// an empty path denotes the package we are currently importing
	pkg := importpkg
	if path != "" {
		pkg = mkpkg(path)
	}
	if pkg.Name == "" {
		pkg.Name = name
	} else if pkg.Name != name {
		Fatalf("importer: inconsistent package names: got %s; want %s (path = %s)", pkg.Name, name, path)
	}
	p.pkgList = append(p.pkgList, pkg)

	return pkg
}

func (p *importer) localname() *Sym {
	// parser.go:hidden_importsym
	name := p.string()
	if name == "" {
		Fatalf("importer: unexpected anonymous name")
	}
	return importpkg.Lookup(name)
}

func (p *importer) newtyp(etype EType) *Type {
	t := typ(etype)
	p.typList = append(p.typList, t)
	return t
}

func (p *importer) typ() *Type {
	// if the type was seen before, i is its index (>= 0)
	i := p.tagOrIndex()
	if i >= 0 {
		return p.typList[i]
	}

	// otherwise, i is the type tag (< 0)
	var t *Type
	switch i {
	case namedTag:
		// parser.go:hidden_importsym
		tsym := p.qualifiedName()

		// parser.go:hidden_pkgtype
		t = pkgtype(tsym)
		importsym(tsym, OTYPE)
		p.typList = append(p.typList, t)

		// read underlying type
		// parser.go:hidden_type
		t0 := p.typ()
		importtype(t, t0) // parser.go:hidden_import

		// interfaces don't have associated methods
		if t0.IsInterface() {
			break
		}

		// read associated methods
		for i := p.int(); i > 0; i-- {
			// parser.go:hidden_fndcl
			name := p.string()
			recv := p.paramList() // TODO(gri) do we need a full param list for the receiver?
			params := p.paramList()
			result := p.paramList()
			inl := p.int()

			pkg := localpkg
			if !exportname(name) {
				pkg = tsym.Pkg
			}
			sym := pkg.Lookup(name)

			n := methodname1(newname(sym), recv[0].Right)
			n.Type = functype(recv[0], params, result)
			checkwidth(n.Type)
			addmethod(sym, n.Type, tsym.Pkg, false, false)
			funchdr(n)

			// (comment from parser.go)
			// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
			// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
			// out by typecheck's lookdot as this $$.ttype. So by providing
			// this back link here we avoid special casing there.
			n.Type.SetNname(n)

			// parser.go:hidden_import
			n.Func.Inl.Set(nil)
			if inl >= 0 {
				if inl != len(p.inlined) {
					panic(fmt.Sprintf("inlined body list inconsistent: %d != %d", inl, len(p.inlined)))
				}
				p.inlined = append(p.inlined, n.Func)
			}
			funcbody(n)
			importlist = append(importlist, n) // TODO(gri) do this only if body is inlineable?
		}

	case arrayTag, sliceTag:
		t = p.newtyp(TARRAY)
		if i == arrayTag {
			t.SetNumElem(p.int64())
		} else {
			t.SetNumElem(sliceBound)
		}
		t.Type = p.typ()

	case dddTag:
		t = p.newtyp(TDDDFIELD)
		t.Type = p.typ()

	case structTag:
		t = p.newtyp(TSTRUCT)
		tostruct0(t, p.fieldList())

	case pointerTag:
		t = p.newtyp(Tptr)
		t.Type = p.typ()

	case signatureTag:
		t = p.newtyp(TFUNC)
		params := p.paramList()
		result := p.paramList()
		functype0(t, nil, params, result)

	case interfaceTag:
		t = p.newtyp(TINTER)
		if p.int() != 0 {
			Fatalf("importer: unexpected embedded interface")
		}
		tointerface0(t, p.methodList())

	case mapTag:
		t = p.newtyp(TMAP)
		t.Down = p.typ() // key
		t.Type = p.typ() // val

	case chanTag:
		t = p.newtyp(TCHAN)
		t.Chan = uint8(p.int())
		t.Type = p.typ()

	default:
		Fatalf("importer: unexpected type (tag = %d)", i)
	}

	if t == nil {
		Fatalf("importer: nil type (type tag = %d)", i)
	}

	return t
}

func (p *importer) qualifiedName() *Sym {
	name := p.string()
	pkg := p.pkg()
	return pkg.Lookup(name)
}

// parser.go:hidden_structdcl_list
func (p *importer) fieldList() []*Node {
	i := p.int()
	if i == 0 {
		return nil
	}
	n := make([]*Node, i)
	for i := range n {
		n[i] = p.field()
	}
	return n
}

// parser.go:hidden_structdcl
func (p *importer) field() *Node {
	sym := p.fieldName()
	typ := p.typ()
	note := p.note()

	var n *Node
	if sym.Name != "" {
		n = Nod(ODCLFIELD, newname(sym), typenod(typ))
	} else {
		// anonymous field - typ must be T or *T and T must be a type name
		s := typ.Sym
		if s == nil && typ.IsPtr() {
			s = typ.Type.Sym // deref
		}
		pkg := importpkg
		if sym != nil {
			pkg = sym.Pkg
		}
		n = embedded(s, pkg)
		n.Right = typenod(typ)
	}
	n.SetVal(note)

	return n
}

func (p *importer) note() (v Val) {
	if s := p.string(); s != "" {
		v.U = s
	}
	return
}

// parser.go:hidden_interfacedcl_list
func (p *importer) methodList() []*Node {
	i := p.int()
	if i == 0 {
		return nil
	}
	n := make([]*Node, i)
	for i := range n {
		n[i] = p.method()
	}
	return n
}

// parser.go:hidden_interfacedcl
func (p *importer) method() *Node {
	sym := p.fieldName()
	params := p.paramList()
	result := p.paramList()
	return Nod(ODCLFIELD, newname(sym), typenod(functype(fakethis(), params, result)))
}

// parser.go:sym,hidden_importsym
func (p *importer) fieldName() *Sym {
	name := p.string()
	pkg := localpkg
	if name == "_" {
		// During imports, unqualified non-exported identifiers are from builtinpkg
		// (see parser.go:sym). The binary exporter only exports blank as a non-exported
		// identifier without qualification.
		pkg = builtinpkg
	} else if name == "?" || name != "" && !exportname(name) {
		if name == "?" {
			name = ""
		}
		pkg = p.pkg()
	}
	return pkg.Lookup(name)
}

// parser.go:ohidden_funarg_list
func (p *importer) paramList() []*Node {
	i := p.int()
	if i == 0 {
		return nil
	}
	// negative length indicates unnamed parameters
	named := true
	if i < 0 {
		i = -i
		named = false
	}
	// i > 0
	n := make([]*Node, i)
	for i := range n {
		n[i] = p.param(named)
	}
	return n
}

// parser.go:hidden_funarg
func (p *importer) param(named bool) *Node {
	typ := p.typ()

	isddd := false
	if typ.Etype == TDDDFIELD {
		// TDDDFIELD indicates wrapped ... slice type
		typ = typSlice(typ.Wrapped())
		isddd = true
	}

	n := Nod(ODCLFIELD, nil, typenod(typ))
	n.Isddd = isddd

	if named {
		name := p.string()
		if name == "" {
			Fatalf("importer: expected named parameter")
		}
		// The parameter package doesn't matter; it's never consulted.
		// We use the builtinpkg per parser.go:sym (line 1181).
		n.Left = newname(builtinpkg.Lookup(name))
	}

	// TODO(gri) This is compiler-specific (escape info).
	// Move into compiler-specific section eventually?
	n.SetVal(p.note())

	return n
}

func (p *importer) value(typ *Type) (x Val) {
	switch tag := p.tagOrIndex(); tag {
	case falseTag:
		x.U = false

	case trueTag:
		x.U = true

	case int64Tag:
		u := new(Mpint)
		u.SetInt64(p.int64())
		u.Rune = typ == idealrune
		x.U = u

	case floatTag:
		f := newMpflt()
		p.float(f)
		if typ == idealint || typ.IsInteger() {
			// uncommon case: large int encoded as float
			u := new(Mpint)
			u.SetFloat(f)
			x.U = u
			break
		}
		x.U = f

	case complexTag:
		u := new(Mpcplx)
		p.float(&u.Real)
		p.float(&u.Imag)
		x.U = u

	case stringTag:
		x.U = p.string()

	case unknownTag:
		Fatalf("importer: unknown constant (importing package with errors)")

	case nilTag:
		x.U = new(NilVal)

	default:
		Fatalf("importer: unexpected value tag %d", tag)
	}

	// verify ideal type
	if typ.IsUntyped() && untype(x.Ctype()) != typ {
		Fatalf("importer: value %v and type %v don't match", x, typ)
	}

	return
}

func (p *importer) float(x *Mpflt) {
	sign := p.int()
	if sign == 0 {
		x.SetFloat64(0)
		return
	}

	exp := p.int()
	mant := new(big.Int).SetBytes([]byte(p.string()))

	m := x.Val.SetInt(mant)
	m.SetMantExp(m, exp-mant.BitLen())
	if sign < 0 {
		m.Neg(m)
	}
}

// ----------------------------------------------------------------------------
// Inlined function bodies

func (p *importer) block() []*Node {
	markdcl()
	// TODO(gri) populate "scope" with function parameters so they can be found
	//           inside the function body
	list := p.nodeList()
	popdcl()
	return list
}

// parser.go:stmt_list
func (p *importer) nodeList() []*Node {
	c := p.int()
	s := make([]*Node, c)
	for i := range s {
		s[i] = p.node()
	}
	return s
}

func (p *importer) node() *Node {
	// TODO(gri) eventually we may need to allocate in each branch
	n := Nod(p.op(), nil, nil)

	switch n.Op {
	// names
	case ONAME, OPACK, ONONAME:
		name := mkname(p.sym())
		// TODO(gri) decide what to do here (this code throws away n)
		/*
			if name.Op != n.Op {
				Fatalf("importer: got node op = %s; want %s", opnames[name.Op], opnames[n.Op])
			}
		*/
		n = name

	case OTYPE:
		if p.bool() {
			n.Sym = p.sym()
		} else {
			n.Type = p.typ()
		}

	case OLITERAL:
		typ := p.typ()
		n.Type = idealType(typ)
		n.SetVal(p.value(typ))

	// expressions
	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
		if p.bool() {
			n.List.Set(p.nodeList())
		}
		n.Left, n.Right = p.nodesOrNil()
		n.Type = p.typ()

	case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
		n.Left = p.node()

	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND,
		OSUB, OXOR:
		n.Left = p.node()
		n.Right = p.node()

	case OADDSTR:
		n.List.Set(p.nodeList())

	case OPTRLIT:
		n.Left = p.node()

	case OSTRUCTLIT:
		n.Type = p.typ()
		n.List.Set(p.nodeList())
		n.Implicit = p.bool()

	case OARRAYLIT, OMAPLIT:
		n.Type = p.typ()
		n.List.Set(p.nodeList())
		n.Implicit = p.bool()

	case OKEY:
		n.Left, n.Right = p.nodesOrNil()

	case OCOPY, OCOMPLEX:
		n.Left = p.node()
		n.Right = p.node()

	case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR:
		// n.Type = p.typ()
		// if p.bool() {
		// 	n.Left = p.node()
		// } else {
		// 	n.List.Set(p.nodeList())
		// }
		x := Nod(OCALL, p.typ().Nod, nil)
		if p.bool() {
			x.List.Set1(p.node())
		} else {
			x.List.Set(p.nodeList())
		}
		return x

	case ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT:
		// see parser.new_dotname
		obj := p.node()
		sel := p.sym()
		if obj.Op == OPACK {
			s := restrictlookup(sel.Name, obj.Name.Pkg)
			obj.Used = true
			return oldname(s)
		}
		return NodSym(OXDOT, obj, sel)

	case ODOTTYPE, ODOTTYPE2:
		n.Left = p.node()
		if p.bool() {
			n.Right = p.node()
		} else {
			n.Type = p.typ()
		}

	case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
		n.Left = p.node()
		n.Right = p.node()

	case OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC,
		ORECOVER, OPRINT, OPRINTN:
		n.Left, _ = p.nodesOrNil()
		n.List.Set(p.nodeList())
		n.Isddd = p.bool()

	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
		n.Left = p.node()
		n.List.Set(p.nodeList())
		n.Isddd = p.bool()

	case OCMPSTR, OCMPIFACE:
		n.Left = p.node()
		n.Right = p.node()
		n.Etype = EType(p.int())

	case OPAREN:
		n.Left = p.node()

	// statements
	case ODCL:
		n.Left = p.node() // TODO(gri) compare with fmt code
		n.Left.Type = p.typ()

	case OAS:
		n.Left, n.Right = p.nodesOrNil()
		n.Colas = p.bool() // TODO(gri) what about complexinit?

	case OASOP:
		n.Left = p.node()
		n.Right = p.node()
		n.Etype = EType(p.int())

	case OAS2, OASWB:
		n.List.Set(p.nodeList())
		n.Rlist.Set(p.nodeList())

	case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
		n.List.Set(p.nodeList())
		n.Rlist.Set(p.nodeList())

	case ORETURN:
		n.List.Set(p.nodeList())

	case OPROC, ODEFER:
		n.Left = p.node()

	case OIF:
		n.Ninit.Set(p.nodeList())
		n.Left = p.node()
		n.Nbody.Set(p.nodeList())
		n.Rlist.Set(p.nodeList())

	case OFOR:
		n.Ninit.Set(p.nodeList())
		n.Left, n.Right = p.nodesOrNil()
		n.Nbody.Set(p.nodeList())

	case ORANGE:
		if p.bool() {
			n.List.Set(p.nodeList())
		}
		n.Right = p.node()
		n.Nbody.Set(p.nodeList())

	case OSELECT, OSWITCH:
		n.Ninit.Set(p.nodeList())
		n.Left, _ = p.nodesOrNil()
		n.List.Set(p.nodeList())

	case OCASE, OXCASE:
		if p.bool() {
			n.List.Set(p.nodeList())
		}
		n.Nbody.Set(p.nodeList())

	case OBREAK, OCONTINUE, OGOTO, OFALL, OXFALL:
		n.Left, _ = p.nodesOrNil()

	case OEMPTY, ODCLCONST:
		// nothing to do

	case OLABEL:
		n.Left = p.node()

	default:
		panic(fmt.Sprintf("importer: %s (%d) node not yet supported", opnames[n.Op], n.Op))
	}

	return n
}

func (p *importer) nodesOrNil() (a, b *Node) {
	ab := p.int()
	if ab&1 != 0 {
		a = p.node()
	}
	if ab&2 != 0 {
		b = p.node()
	}
	return
}

func (p *importer) sym() *Sym {
	return p.fieldName()
}

func (p *importer) bool() bool {
	return p.int() != 0
}

func (p *importer) op() Op {
	return Op(p.int())
}

// ----------------------------------------------------------------------------
// Low-level decoders

func (p *importer) tagOrIndex() int {
	if p.debugFormat {
		p.marker('t')
	}

	return int(p.rawInt64())
}

func (p *importer) int() int {
	x := p.int64()
	if int64(int(x)) != x {
		Fatalf("importer: exported integer too large")
	}
	return int(x)
}

func (p *importer) int64() int64 {
	if p.debugFormat {
		p.marker('i')
	}

	return p.rawInt64()
}

func (p *importer) string() string {
	if p.debugFormat {
		p.marker('s')
	}

	if n := int(p.rawInt64()); n > 0 {
		if cap(p.buf) < n {
			p.buf = make([]byte, n)
		} else {
			p.buf = p.buf[:n]
		}
		for i := range p.buf {
			p.buf[i] = p.byte()
		}
		return string(p.buf)
	}

	return ""
}

func (p *importer) marker(want byte) {
	if got := p.byte(); got != want {
		Fatalf("importer: incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
	}

	pos := p.read
	if n := int(p.rawInt64()); n != pos {
		Fatalf("importer: incorrect position: got %d; want %d", n, pos)
	}
}

// rawInt64 should only be used by low-level decoders
func (p *importer) rawInt64() int64 {
	i, err := binary.ReadVarint(p)
	if err != nil {
		Fatalf("importer: read error: %v", err)
	}
	return i
}

// needed for binary.ReadVarint in rawInt64
func (p *importer) ReadByte() (byte, error) {
	return p.byte(), nil
}

// byte is the bottleneck interface for reading from p.in.
// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
func (p *importer) byte() byte {
	c, err := p.in.ReadByte()
	p.read++
	if err != nil {
		Fatalf("importer: read error: %v", err)
	}
	if c == '|' {
		c, err = p.in.ReadByte()
		p.read++
		if err != nil {
			Fatalf("importer: read error: %v", err)
		}
		switch c {
		case 'S':
			c = '$'
		case '|':
			// nothing to do
		default:
			Fatalf("importer: unexpected escape sequence in export data")
		}
	}
	return c
}
