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

#include	<u.h>
#include	<libc.h>
#include	"go.h"

enum
{
	Snorm		= 0,
	Strue,
	Sfalse,
	Stype,

	Tdefault,	// default case
	Texprconst,	// normal constant case
	Texprvar,	// normal variable case
	Ttypenil,	// case nil
	Ttypeconst,	// type hashes
	Ttypevar,	// interface type

	Ncase	= 4,	// count needed to split
};

typedef	struct	Case	Case;
struct	Case
{
	Node*	node;		// points at case statement
	uint32	hash;		// hash of a type switch
	uint8	type;		// type of case
	uint8	diag;		// suppress multiple diagnostics
	uint16	ordinal;	// position in switch
	Case*	link;		// linked list to link
};
#define	C	((Case*)nil)
/*c2go Case *C; */

void
dumpcase(Case *c0)
{
	Case *c;

	for(c=c0; c!=C; c=c->link) {
		switch(c->type) {
		case Tdefault:
			print("case-default\n");
			print("	ord=%d\n", c->ordinal);
			break;
		case Texprconst:
			print("case-exprconst\n");
			print("	ord=%d\n", c->ordinal);
			break;
		case Texprvar:
			print("case-exprvar\n");
			print("	ord=%d\n", c->ordinal);
			print("	op=%O\n", c->node->left->op);
			break;
		case Ttypenil:
			print("case-typenil\n");
			print("	ord=%d\n", c->ordinal);
			break;
		case Ttypeconst:
			print("case-typeconst\n");
			print("	ord=%d\n", c->ordinal);
			print("	hash=%ux\n", c->hash);
			break;
		case Ttypevar:
			print("case-typevar\n");
			print("	ord=%d\n", c->ordinal);
			break;
		default:
			print("case-???\n");
			print("	ord=%d\n", c->ordinal);
			print("	op=%O\n", c->node->left->op);
			print("	hash=%ux\n", c->hash);
			break;
		}
	}
	print("\n");
}

static int
ordlcmp(Case *c1, Case *c2)
{
	// sort default first
	if(c1->type == Tdefault)
		return -1;
	if(c2->type == Tdefault)
		return +1;

	// sort nil second
	if(c1->type == Ttypenil)
		return -1;
	if(c2->type == Ttypenil)
		return +1;

	// sort by ordinal
	if(c1->ordinal > c2->ordinal)
		return +1;
	if(c1->ordinal < c2->ordinal)
		return -1;
	return 0;
}

static int
exprcmp(Case *c1, Case *c2)
{
	int ct, n;
	Node *n1, *n2;

	// sort non-constants last
	if(c1->type != Texprconst)
		return +1;
	if(c2->type != Texprconst)
		return -1;

	n1 = c1->node->left;
	n2 = c2->node->left;

	// sort by type (for switches on interface)
	ct = n1->val.ctype;
	if(ct != n2->val.ctype)
		return ct - n2->val.ctype;
	if(!eqtype(n1->type, n2->type)) {
		if(n1->type->vargen > n2->type->vargen)
			return +1;
		else
			return -1;
	}

	// sort by constant value
	n = 0;
	switch(ct) {
	case CTFLT:
		n = mpcmpfltflt(n1->val.u.fval, n2->val.u.fval);
		break;
	case CTINT:
	case CTRUNE:
		n = mpcmpfixfix(n1->val.u.xval, n2->val.u.xval);
		break;
	case CTSTR:
		n = cmpslit(n1, n2);
		break;
	}

	return n;
}

static int
typecmp(Case *c1, Case *c2)
{

	// sort non-constants last
	if(c1->type != Ttypeconst)
		return +1;
	if(c2->type != Ttypeconst)
		return -1;

	// sort by hash code
	if(c1->hash > c2->hash)
		return +1;
	if(c1->hash < c2->hash)
		return -1;

	// sort by ordinal so duplicate error
	// happens on later case.
	if(c1->ordinal > c2->ordinal)
		return +1;
	if(c1->ordinal < c2->ordinal)
		return -1;
	return 0;
}

static Case*
csort(Case *l, int(*f)(Case*, Case*))
{
	Case *l1, *l2, *le;

	if(l == C || l->link == C)
		return l;

	l1 = l;
	l2 = l;
	for(;;) {
		l2 = l2->link;
		if(l2 == C)
			break;
		l2 = l2->link;
		if(l2 == C)
			break;
		l1 = l1->link;
	}

	l2 = l1->link;
	l1->link = C;
	l1 = csort(l, f);
	l2 = csort(l2, f);

	/* set up lead element */
	if((*f)(l1, l2) < 0) {
		l = l1;
		l1 = l1->link;
	} else {
		l = l2;
		l2 = l2->link;
	}
	le = l;

	for(;;) {
		if(l1 == C) {
			while(l2) {
				le->link = l2;
				le = l2;
				l2 = l2->link;
			}
			le->link = C;
			break;
		}
		if(l2 == C) {
			while(l1) {
				le->link = l1;
				le = l1;
				l1 = l1->link;
			}
			break;
		}
		if((*f)(l1, l2) < 0) {
			le->link = l1;
			le = l1;
			l1 = l1->link;
		} else {
			le->link = l2;
			le = l2;
			l2 = l2->link;
		}
	}
	le->link = C;
	return l;
}

static Node*
newlabel(void)
{
	static int label;

	label++;
	snprint(namebuf, sizeof(namebuf), "%.6d", label);
	return newname(lookup(namebuf));
}

/*
 * build separate list of statements and cases
 * make labels between cases and statements
 * deal with fallthrough, break, unreachable statements
 */
static void
casebody(Node *sw, Node *typeswvar)
{
	Node *n, *c, *last;
	Node *def;
	NodeList *cas, *stat, *l, *lc;
	Node *go, *br;
	int32 lno, needvar;

	if(sw->list == nil)
		return;

	lno = setlineno(sw);

	cas = nil;	// cases
	stat = nil;	// statements
	def = N;	// defaults
	br = nod(OBREAK, N, N);

	for(l=sw->list; l; l=l->next) {
		n = l->n;
		setlineno(n);
		if(n->op != OXCASE)
			fatal("casebody %O", n->op);
		n->op = OCASE;
		needvar = count(n->list) != 1 || n->list->n->op == OLITERAL;

		go = nod(OGOTO, newlabel(), N);
		if(n->list == nil) {
			if(def != N)
				yyerror("more than one default case");
			// reuse original default case
			n->right = go;
			def = n;
		}

		if(n->list != nil && n->list->next == nil) {
			// one case - reuse OCASE node.
			c = n->list->n;
			n->left = c;
			n->right = go;
			n->list = nil;
			cas = list(cas, n);
		} else {
			// expand multi-valued cases
			for(lc=n->list; lc; lc=lc->next) {
				c = lc->n;
				cas = list(cas, nod(OCASE, c, go));
			}
		}

		stat = list(stat, nod(OLABEL, go->left, N));
		if(typeswvar && needvar && n->nname != N) {
			NodeList *l;

			l = list1(nod(ODCL, n->nname, N));
			l = list(l, nod(OAS, n->nname, typeswvar));
			typechecklist(l, Etop);
			stat = concat(stat, l);
		}
		stat = concat(stat, n->nbody);

		// botch - shouldn't fall thru declaration
		last = stat->end->n;
		if(last->xoffset == n->xoffset && last->op == OXFALL) {
			if(typeswvar) {
				setlineno(last);
				yyerror("cannot fallthrough in type switch");
			}
			if(l->next == nil) {
				setlineno(last);
				yyerror("cannot fallthrough final case in switch");
			}
			last->op = OFALL;
		} else
			stat = list(stat, br);
	}

	stat = list(stat, br);
	if(def)
		cas = list(cas, def);

	sw->list = cas;
	sw->nbody = stat;
	lineno = lno;
}

static Case*
mkcaselist(Node *sw, int arg)
{
	Node *n;
	Case *c, *c1, *c2;
	NodeList *l;
	int ord;

	c = C;
	ord = 0;

	for(l=sw->list; l; l=l->next) {
		n = l->n;
		c1 = mal(sizeof(*c1));
		c1->link = c;
		c = c1;

		ord++;
		if((uint16)ord != ord)
			fatal("too many cases in switch");
		c->ordinal = ord;
		c->node = n;

		if(n->left == N) {
			c->type = Tdefault;
			continue;
		}

		switch(arg) {
		case Stype:
			c->hash = 0;
			if(n->left->op == OLITERAL) {
				c->type = Ttypenil;
				continue;
			}
			if(istype(n->left->type, TINTER)) {
				c->type = Ttypevar;
				continue;
			}

			c->hash = typehash(n->left->type);
			c->type = Ttypeconst;
			continue;

		case Snorm:
		case Strue:
		case Sfalse:
			c->type = Texprvar;
			c->hash = typehash(n->left->type);
			switch(consttype(n->left)) {
			case CTFLT:
			case CTINT:
			case CTRUNE:
			case CTSTR:
				c->type = Texprconst;
			}
			continue;
		}
	}

	if(c == C)
		return C;

	// sort by value and diagnose duplicate cases
	switch(arg) {
	case Stype:
		c = csort(c, typecmp);
		for(c1=c; c1!=C; c1=c1->link) {
			for(c2=c1->link; c2!=C && c2->hash==c1->hash; c2=c2->link) {
				if(c1->type == Ttypenil || c1->type == Tdefault)
					break;
				if(c2->type == Ttypenil || c2->type == Tdefault)
					break;
				if(!eqtype(c1->node->left->type, c2->node->left->type))
					continue;
				yyerrorl(c2->node->lineno, "duplicate case %T in type switch\n\tprevious case at %L", c2->node->left->type, c1->node->lineno);
			}
		}
		break;
	case Snorm:
	case Strue:
	case Sfalse:
		c = csort(c, exprcmp);
		for(c1=c; c1->link!=C; c1=c1->link) {
			if(exprcmp(c1, c1->link) != 0)
				continue;
			setlineno(c1->link->node);
			yyerror("duplicate case %N in switch\n\tprevious case at %L", c1->node->left, c1->node->lineno);
		}
		break;
	}

	// put list back in processing order
	c = csort(c, ordlcmp);
	return c;
}

static	Node*	exprname;

static Node*
exprbsw(Case *c0, int ncase, int arg)
{
	NodeList *cas;
	Node *a, *n;
	Case *c;
	int i, half, lno;

	cas = nil;
	if(ncase < Ncase) {
		for(i=0; i<ncase; i++) {
			n = c0->node;
			lno = setlineno(n);

			if((arg != Strue && arg != Sfalse) ||
			   assignop(n->left->type, exprname->type, nil) == OCONVIFACE ||
			   assignop(exprname->type, n->left->type, nil) == OCONVIFACE) {
				a = nod(OIF, N, N);
				a->ntest = nod(OEQ, exprname, n->left);	// if name == val
				typecheck(&a->ntest, Erv);
				a->nbody = list1(n->right);			// then goto l
			} else if(arg == Strue) {
				a = nod(OIF, N, N);
				a->ntest = n->left;			// if val
				a->nbody = list1(n->right);			// then goto l
			} else { // arg == Sfalse
				a = nod(OIF, N, N);
				a->ntest = nod(ONOT, n->left, N);	// if !val
				typecheck(&a->ntest, Erv);
				a->nbody = list1(n->right);			// then goto l
			}

			cas = list(cas, a);
			c0 = c0->link;
			lineno = lno;
		}
		return liststmt(cas);
	}

	// find the middle and recur
	c = c0;
	half = ncase>>1;
	for(i=1; i<half; i++)
		c = c->link;
	a = nod(OIF, N, N);
	a->ntest = nod(OLE, exprname, c->node->left);
	typecheck(&a->ntest, Erv);
	a->nbody = list1(exprbsw(c0, half, arg));
	a->nelse = list1(exprbsw(c->link, ncase-half, arg));
	return a;
}

/*
 * normal (expression) switch.
 * rebuild case statements into if .. goto
 */
static void
exprswitch(Node *sw)
{
	Node *def;
	NodeList *cas;
	Node *a;
	Case *c0, *c, *c1;
	Type *t;
	int arg, ncase;

	casebody(sw, N);

	arg = Snorm;
	if(isconst(sw->ntest, CTBOOL)) {
		arg = Strue;
		if(sw->ntest->val.u.bval == 0)
			arg = Sfalse;
	}
	walkexpr(&sw->ntest, &sw->ninit);
	t = sw->type;
	if(t == T)
		return;

	/*
	 * convert the switch into OIF statements
	 */
	exprname = N;
	cas = nil;
	if(arg == Strue || arg == Sfalse)
		exprname = nodbool(arg == Strue);
	else if(consttype(sw->ntest) >= 0)
		// leave constants to enable dead code elimination (issue 9608)
		exprname = sw->ntest;
	else {
		exprname = temp(sw->ntest->type);
		cas = list1(nod(OAS, exprname, sw->ntest));
		typechecklist(cas, Etop);
	}

	c0 = mkcaselist(sw, arg);
	if(c0 != C && c0->type == Tdefault) {
		def = c0->node->right;
		c0 = c0->link;
	} else {
		def = nod(OBREAK, N, N);
	}

loop:
	if(c0 == C) {
		cas = list(cas, def);
		sw->nbody = concat(cas, sw->nbody);
		sw->list = nil;
		walkstmtlist(sw->nbody);
		return;
	}

	// deal with the variables one-at-a-time
	if(!okforcmp[t->etype] || c0->type != Texprconst) {
		a = exprbsw(c0, 1, arg);
		cas = list(cas, a);
		c0 = c0->link;
		goto loop;
	}

	// do binary search on run of constants
	ncase = 1;
	for(c=c0; c->link!=C; c=c->link) {
		if(c->link->type != Texprconst)
			break;
		ncase++;
	}

	// break the chain at the count
	c1 = c->link;
	c->link = C;

	// sort and compile constants
	c0 = csort(c0, exprcmp);
	a = exprbsw(c0, ncase, arg);
	cas = list(cas, a);

	c0 = c1;
	goto loop;

}

static	Node*	hashname;
static	Node*	facename;
static	Node*	boolname;

static Node*
typeone(Node *t)
{
	NodeList *init;
	Node *a, *b, *var;

	var = t->nname;
	init = nil;
	if(var == N) {
		typecheck(&nblank, Erv | Easgn);
		var = nblank;
	} else
		init = list1(nod(ODCL, var, N));

	a = nod(OAS2, N, N);
	a->list = list(list1(var), boolname);	// var,bool =
	b = nod(ODOTTYPE, facename, N);
	b->type = t->left->type;		// interface.(type)
	a->rlist = list1(b);
	typecheck(&a, Etop);
	init = list(init, a);

	b = nod(OIF, N, N);
	b->ntest = boolname;
	b->nbody = list1(t->right);		// if bool { goto l }
	a = liststmt(list(init, b));
	return a;
}

static Node*
typebsw(Case *c0, int ncase)
{
	NodeList *cas;
	Node *a, *n;
	Case *c;
	int i, half;

	cas = nil;

	if(ncase < Ncase) {
		for(i=0; i<ncase; i++) {
			n = c0->node;
			if(c0->type != Ttypeconst)
				fatal("typebsw");
			a = nod(OIF, N, N);
			a->ntest = nod(OEQ, hashname, nodintconst(c0->hash));
			typecheck(&a->ntest, Erv);
			a->nbody = list1(n->right);
			cas = list(cas, a);
			c0 = c0->link;
		}
		return liststmt(cas);
	}

	// find the middle and recur
	c = c0;
	half = ncase>>1;
	for(i=1; i<half; i++)
		c = c->link;
	a = nod(OIF, N, N);
	a->ntest = nod(OLE, hashname, nodintconst(c->hash));
	typecheck(&a->ntest, Erv);
	a->nbody = list1(typebsw(c0, half));
	a->nelse = list1(typebsw(c->link, ncase-half));
	return a;
}

/*
 * convert switch of the form
 *	switch v := i.(type) { case t1: ..; case t2: ..; }
 * into if statements
 */
static void
typeswitch(Node *sw)
{
	Node *def;
	NodeList *cas, *hash;
	Node *a, *n;
	Case *c, *c0, *c1;
	int ncase;
	Type *t;
	Val v;

	if(sw->ntest == nil)
		return;
	if(sw->ntest->right == nil) {
		setlineno(sw);
		yyerror("type switch must have an assignment");
		return;
	}
	walkexpr(&sw->ntest->right, &sw->ninit);
	if(!istype(sw->ntest->right->type, TINTER)) {
		yyerror("type switch must be on an interface");
		return;
	}
	cas = nil;

	/*
	 * predeclare temporary variables
	 * and the boolean var
	 */
	facename = temp(sw->ntest->right->type);
	a = nod(OAS, facename, sw->ntest->right);
	typecheck(&a, Etop);
	cas = list(cas, a);

	casebody(sw, facename);

	boolname = temp(types[TBOOL]);
	typecheck(&boolname, Erv);

	hashname = temp(types[TUINT32]);
	typecheck(&hashname, Erv);

	t = sw->ntest->right->type;
	if(isnilinter(t))
		a = syslook("efacethash", 1);
	else
		a = syslook("ifacethash", 1);
	argtype(a, t);
	a = nod(OCALL, a, N);
	a->list = list1(facename);
	a = nod(OAS, hashname, a);
	typecheck(&a, Etop);
	cas = list(cas, a);

	c0 = mkcaselist(sw, Stype);
	if(c0 != C && c0->type == Tdefault) {
		def = c0->node->right;
		c0 = c0->link;
	} else {
		def = nod(OBREAK, N, N);
	}
	
	/*
	 * insert if statement into each case block
	 */
	for(c=c0; c!=C; c=c->link) {
		n = c->node;
		switch(c->type) {

		case Ttypenil:
			v.ctype = CTNIL;
			a = nod(OIF, N, N);
			a->ntest = nod(OEQ, facename, nodlit(v));
			typecheck(&a->ntest, Erv);
			a->nbody = list1(n->right);		// if i==nil { goto l }
			n->right = a;
			break;
		
		case Ttypevar:
		case Ttypeconst:
			n->right = typeone(n);
			break;
		}
	}

	/*
	 * generate list of if statements, binary search for constant sequences
	 */
	while(c0 != C) {
		if(c0->type != Ttypeconst) {
			n = c0->node;
			cas = list(cas, n->right);
			c0=c0->link;
			continue;
		}
		
		// identify run of constants
		c1 = c = c0;
		while(c->link!=C && c->link->type==Ttypeconst)
			c = c->link;
		c0 = c->link;
		c->link = nil;

		// sort by hash
		c1 = csort(c1, typecmp);
		
		// for debugging: linear search
		if(0) {
			for(c=c1; c!=C; c=c->link) {
				n = c->node;
				cas = list(cas, n->right);
			}
			continue;
		}

		// combine adjacent cases with the same hash
		ncase = 0;
		for(c=c1; c!=C; c=c->link) {
			ncase++;
			hash = list1(c->node->right);
			while(c->link != C && c->link->hash == c->hash) {
				hash = list(hash, c->link->node->right);
				c->link = c->link->link;
			}
			c->node->right = liststmt(hash);
		}
		
		// binary search among cases to narrow by hash
		cas = list(cas, typebsw(c1, ncase));
	}
	if(nerrors == 0) {
		cas = list(cas, def);
		sw->nbody = concat(cas, sw->nbody);
		sw->list = nil;
		walkstmtlist(sw->nbody);
	}
}

void
walkswitch(Node *sw)
{
	/*
	 * reorder the body into (OLIST, cases, statements)
	 * cases have OGOTO into statements.
	 * both have inserted OBREAK statements
	 */
	if(sw->ntest == N) {
		sw->ntest = nodbool(1);
		typecheck(&sw->ntest, Erv);
	}

	if(sw->ntest->op == OTYPESW) {
		typeswitch(sw);
//dump("sw", sw);
		return;
	}
	exprswitch(sw);
	// Discard old AST elements after a walk. They can confuse racewealk.
	sw->ntest = nil;
	sw->list = nil;
}

/*
 * type check switch statement
 */
void
typecheckswitch(Node *n)
{
	int top, lno, ptr;
	char *nilonly;
	Type *t, *badtype, *missing, *have;
	NodeList *l, *ll;
	Node *ncase, *nvar;
	Node *def;

	lno = lineno;
	typechecklist(n->ninit, Etop);
	nilonly = nil;

	if(n->ntest != N && n->ntest->op == OTYPESW) {
		// type switch
		top = Etype;
		typecheck(&n->ntest->right, Erv);
		t = n->ntest->right->type;
		if(t != T && t->etype != TINTER)
			yyerror("cannot type switch on non-interface value %lN", n->ntest->right);
	} else {
		// value switch
		top = Erv;
		if(n->ntest) {
			typecheck(&n->ntest, Erv);
			defaultlit(&n->ntest, T);
			t = n->ntest->type;
		} else
			t = types[TBOOL];
		if(t) {
			if(!okforeq[t->etype])
				yyerror("cannot switch on %lN", n->ntest);
			else if(t->etype == TARRAY && !isfixedarray(t))
				nilonly = "slice";
			else if(t->etype == TARRAY && isfixedarray(t) && algtype1(t, nil) == ANOEQ)
				yyerror("cannot switch on %lN", n->ntest);
			else if(t->etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ)
				yyerror("cannot switch on %lN (struct containing %T cannot be compared)", n->ntest, badtype);
			else if(t->etype == TFUNC)
				nilonly = "func";
			else if(t->etype == TMAP)
				nilonly = "map";
		}
	}
	n->type = t;

	def = N;
	for(l=n->list; l; l=l->next) {
		ncase = l->n;
		setlineno(n);
		if(ncase->list == nil) {
			// default
			if(def != N)
				yyerror("multiple defaults in switch (first at %L)", def->lineno);
			else
				def = ncase;
		} else {
			for(ll=ncase->list; ll; ll=ll->next) {
				setlineno(ll->n);
				typecheck(&ll->n, Erv | Etype);
				if(ll->n->type == T || t == T)
					continue;
				setlineno(ncase);
				switch(top) {
				case Erv:	// expression switch
					defaultlit(&ll->n, t);
					if(ll->n->op == OTYPE)
						yyerror("type %T is not an expression", ll->n->type);
					else if(ll->n->type != T && !assignop(ll->n->type, t, nil) && !assignop(t, ll->n->type, nil)) {
						if(n->ntest)
							yyerror("invalid case %N in switch on %N (mismatched types %T and %T)", ll->n, n->ntest, ll->n->type, t);
						else
							yyerror("invalid case %N in switch (mismatched types %T and bool)", ll->n, ll->n->type);
					} else if(nilonly && !isconst(ll->n, CTNIL)) {
						yyerror("invalid case %N in switch (can only compare %s %N to nil)", ll->n, nilonly, n->ntest);
					}
					break;
				case Etype:	// type switch
					if(ll->n->op == OLITERAL && istype(ll->n->type, TNIL)) {
						;
					} else if(ll->n->op != OTYPE && ll->n->type != T) {  // should this be ||?
						yyerror("%lN is not a type", ll->n);
						// reset to original type
						ll->n = n->ntest->right;
					} else if(ll->n->type->etype != TINTER && t->etype == TINTER && !implements(ll->n->type, t, &missing, &have, &ptr)) {
						if(have && !missing->broke && !have->broke)
							yyerror("impossible type switch case: %lN cannot have dynamic type %T"
								" (wrong type for %S method)\n\thave %S%hT\n\twant %S%hT",
								n->ntest->right, ll->n->type, missing->sym, have->sym, have->type,
								missing->sym, missing->type);
						else if(!missing->broke)
							yyerror("impossible type switch case: %lN cannot have dynamic type %T"
								" (missing %S method)", n->ntest->right, ll->n->type, missing->sym);
					}
					break;
				}
			}
		}
		if(top == Etype && n->type != T) {
			ll = ncase->list;
			nvar = ncase->nname;
			if(nvar != N) {
				if(ll && ll->next == nil && ll->n->type != T && !istype(ll->n->type, TNIL)) {
					// single entry type switch
					nvar->ntype = typenod(ll->n->type);
				} else {
					// multiple entry type switch or default
					nvar->ntype = typenod(n->type);
				}
				typecheck(&nvar, Erv | Easgn);
				ncase->nname = nvar;
			}
		}
		typechecklist(ncase->nbody, Etop);
	}

	lineno = lno;
}
