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

// This package aids in the testing of code that uses channels.
package script

import (
	"fmt";
	"os";
	"rand";
	"reflect";
	"strings";
)

// An Event is an element in a partially ordered set that either sends a value
// to a channel or expects a value from a channel.
type Event struct {
	name		string;
	occurred	bool;
	predecessors	[]*Event;
	action		action;
}

type action interface {
	// getSend returns nil if the action is not a send action.
	getSend() sendAction;
	// getRecv returns nil if the action is not a receive action.
	getRecv() recvAction;
	// getChannel returns the channel that the action operates on.
	getChannel() interface{};
}

type recvAction interface {
	recvMatch(interface{}) bool;
}

type sendAction interface {
	send();
}

// isReady returns true if all the predecessors of an Event have occurred.
func (e Event) isReady() bool {
	for _, predecessor := range e.predecessors {
		if !predecessor.occurred {
			return false
		}
	}

	return true;
}

// A Recv action reads a value from a channel and uses reflect.DeepMatch to
// compare it with an expected value.
type Recv struct {
	Channel		interface{};
	Expected	interface{};
}

func (r Recv) getRecv() recvAction	{ return r }

func (Recv) getSend() sendAction	{ return nil }

func (r Recv) getChannel() interface{}	{ return r.Channel }

func (r Recv) recvMatch(chanEvent interface{}) bool {
	c, ok := chanEvent.(channelRecv);
	if !ok || c.channel != r.Channel {
		return false
	}

	return reflect.DeepEqual(c.value, r.Expected);
}

// A RecvMatch action reads a value from a channel and calls a function to
// determine if the value matches.
type RecvMatch struct {
	Channel	interface{};
	Match	func(interface{}) bool;
}

func (r RecvMatch) getRecv() recvAction	{ return r }

func (RecvMatch) getSend() sendAction	{ return nil }

func (r RecvMatch) getChannel() interface{}	{ return r.Channel }

func (r RecvMatch) recvMatch(chanEvent interface{}) bool {
	c, ok := chanEvent.(channelRecv);
	if !ok || c.channel != r.Channel {
		return false
	}

	return r.Match(c.value);
}

// A Closed action matches if the given channel is closed. The closing is
// treated as an event, not a state, thus Closed will only match once for a
// given channel.
type Closed struct {
	Channel interface{};
}

func (r Closed) getRecv() recvAction	{ return r }

func (Closed) getSend() sendAction	{ return nil }

func (r Closed) getChannel() interface{}	{ return r.Channel }

func (r Closed) recvMatch(chanEvent interface{}) bool {
	c, ok := chanEvent.(channelClosed);
	if !ok || c.channel != r.Channel {
		return false
	}

	return true;
}

// A Send action sends a value to a channel. The value must match the
// type of the channel exactly unless the channel if of type chan interface{}.
type Send struct {
	Channel	interface{};
	Value	interface{};
}

func (Send) getRecv() recvAction	{ return nil }

func (s Send) getSend() sendAction	{ return s }

func (s Send) getChannel() interface{}	{ return s.Channel }

func newEmptyInterface(args ...) reflect.Value {
	return reflect.NewValue(args).(*reflect.StructValue).Field(0)
}

func (s Send) send() {
	// With reflect.ChanValue.Send, we must match the types exactly. So, if
	// s.Channel is a chan interface{} we convert s.Value to an interface{}
	// first.
	c := reflect.NewValue(s.Channel).(*reflect.ChanValue);
	var v reflect.Value;
	if iface, ok := c.Type().(*reflect.ChanType).Elem().(*reflect.InterfaceType); ok && iface.NumMethod() == 0 {
		v = newEmptyInterface(s.Value)
	} else {
		v = reflect.NewValue(s.Value)
	}
	c.Send(v);
}

// A Close action closes the given channel.
type Close struct {
	Channel interface{};
}

func (Close) getRecv() recvAction	{ return nil }

func (s Close) getSend() sendAction	{ return s }

func (s Close) getChannel() interface{}	{ return s.Channel }

func (s Close) send()	{ reflect.NewValue(s.Channel).(*reflect.ChanValue).Close() }

// A ReceivedUnexpected error results if no active Events match a value
// received from a channel.
type ReceivedUnexpected struct {
	Value	interface{};
	ready	[]*Event;
}

func (r ReceivedUnexpected) String() string {
	names := make([]string, len(r.ready));
	for i, v := range r.ready {
		names[i] = v.name
	}
	return fmt.Sprintf("received unexpected value on one of the channels: %#v. Runnable events: %s", r.Value, strings.Join(names, ", "));
}

// A SetupError results if there is a error with the configuration of a set of
// Events.
type SetupError string

func (s SetupError) String() string	{ return string(s) }

func NewEvent(name string, predecessors []*Event, action action) *Event {
	e := &Event{name, false, predecessors, action};
	return e;
}

// Given a set of Events, Perform repeatedly iterates over the set and finds the
// subset of ready Events (that is, all of their predecessors have
// occurred). From that subset, it pseudo-randomly selects an Event to perform.
// If the Event is a send event, the send occurs and Perform recalculates the ready
// set. If the event is a receive event, Perform waits for a value from any of the
// channels that are contained in any of the events. That value is then matched
// against the ready events. The first event that matches is considered to
// have occurred and Perform recalculates the ready set.
//
// Perform continues this until all Events have occurred.
//
// Note that uncollected goroutines may still be reading from any of the
// channels read from after Perform returns.
//
// For example, consider the problem of testing a function that reads values on
// one channel and echos them to two output channels. To test this we would
// create three events: a send event and two receive events. Each of the
// receive events must list the send event as a predecessor but there is no
// ordering between the receive events.
//
//  send := NewEvent("send", nil, Send{c, 1});
//  recv1 := NewEvent("recv 1", []*Event{send}, Recv{c, 1});
//  recv2 := NewEvent("recv 2", []*Event{send}, Recv{c, 1});
//  Perform(0, []*Event{send, recv1, recv2});
//
// At first, only the send event would be in the ready set and thus Perform will
// send a value to the input channel. Now the two receive events are ready and
// Perform will match each of them against the values read from the output channels.
//
// It would be invalid to list one of the receive events as a predecessor of
// the other. At each receive step, all the receive channels are considered,
// thus Perform may see a value from a channel that is not in the current ready
// set and fail.
func Perform(seed int64, events []*Event) (err os.Error) {
	r := rand.New(rand.NewSource(seed));

	channels, err := getChannels(events);
	if err != nil {
		return
	}
	multiplex := make(chan interface{});
	for _, channel := range channels {
		go recvValues(multiplex, channel)
	}

Outer:
	for {
		ready, err := readyEvents(events);
		if err != nil {
			return err
		}

		if len(ready) == 0 {
			// All events occurred.
			break
		}

		event := ready[r.Intn(len(ready))];
		if send := event.action.getSend(); send != nil {
			send.send();
			event.occurred = true;
			continue;
		}

		v := <-multiplex;
		for _, event := range ready {
			if recv := event.action.getRecv(); recv != nil && recv.recvMatch(v) {
				event.occurred = true;
				continue Outer;
			}
		}

		return ReceivedUnexpected{v, ready};
	}

	return nil;
}

// getChannels returns all the channels listed in any receive events.
func getChannels(events []*Event) ([]interface{}, os.Error) {
	channels := make([]interface{}, len(events));

	j := 0;
	for _, event := range events {
		if recv := event.action.getRecv(); recv == nil {
			continue
		}
		c := event.action.getChannel();
		if _, ok := reflect.NewValue(c).(*reflect.ChanValue); !ok {
			return nil, SetupError("one of the channel values is not a channel")
		}

		duplicate := false;
		for _, other := range channels[0:j] {
			if c == other {
				duplicate = true;
				break;
			}
		}

		if !duplicate {
			channels[j] = c;
			j++;
		}
	}

	return channels[0:j], nil;
}

// recvValues is a multiplexing helper function. It reads values from the given
// channel repeatedly, wrapping them up as either a channelRecv or
// channelClosed structure, and forwards them to the multiplex channel.
func recvValues(multiplex chan<- interface{}, channel interface{}) {
	c := reflect.NewValue(channel).(*reflect.ChanValue);

	for {
		v := c.Recv();
		if c.Closed() {
			multiplex <- channelClosed{channel};
			return;
		}

		multiplex <- channelRecv{channel, v.Interface()};
	}
}

type channelClosed struct {
	channel interface{};
}

type channelRecv struct {
	channel	interface{};
	value	interface{};
}

// readyEvents returns the subset of events that are ready.
func readyEvents(events []*Event) ([]*Event, os.Error) {
	ready := make([]*Event, len(events));

	j := 0;
	eventsWaiting := false;
	for _, event := range events {
		if event.occurred {
			continue
		}

		eventsWaiting = true;
		if event.isReady() {
			ready[j] = event;
			j++;
		}
	}

	if j == 0 && eventsWaiting {
		names := make([]string, len(events));
		for _, event := range events {
			if event.occurred {
				continue
			}
			names[j] = event.name;
		}

		return nil, SetupError("dependency cycle in events. These events are waiting to run but cannot: " + strings.Join(names, ", "));
	}

	return ready[0:j], nil;
}
