package matchers

import (
	"fmt"
	"reflect"

	"github.com/onsi/gomega/format"
)

type ReceiveMatcher struct {
	Arg           interface{}
	receivedValue reflect.Value
	channelClosed bool
}

func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err error) {
	if !isChan(actual) {
		return false, fmt.Errorf("ReceiveMatcher expects a channel.  Got:\n%s", format.Object(actual, 1))
	}

	channelType := reflect.TypeOf(actual)
	channelValue := reflect.ValueOf(actual)

	if channelType.ChanDir() == reflect.SendDir {
		return false, fmt.Errorf("ReceiveMatcher matcher cannot be passed a send-only channel.  Got:\n%s", format.Object(actual, 1))
	}

	var subMatcher omegaMatcher
	var hasSubMatcher bool

	if matcher.Arg != nil {
		subMatcher, hasSubMatcher = (matcher.Arg).(omegaMatcher)
		if !hasSubMatcher {
			argType := reflect.TypeOf(matcher.Arg)
			if argType.Kind() != reflect.Ptr {
				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(matcher.Arg, 1))
			}

			assignable := channelType.Elem().AssignableTo(argType.Elem())
			if !assignable {
				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(matcher.Arg, 1))
			}
		}
	}

	winnerIndex, value, open := reflect.Select([]reflect.SelectCase{
		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue},
		reflect.SelectCase{Dir: reflect.SelectDefault},
	})

	var closed bool
	var didReceive bool
	if winnerIndex == 0 {
		closed = !open
		didReceive = open
	}
	matcher.channelClosed = closed

	if closed {
		return false, nil
	}

	if hasSubMatcher {
		if didReceive {
			matcher.receivedValue = value
			return subMatcher.Match(matcher.receivedValue.Interface())
		} else {
			return false, nil
		}
	}

	if didReceive {
		if matcher.Arg != nil {
			outValue := reflect.ValueOf(matcher.Arg)
			reflect.Indirect(outValue).Set(value)
		}

		return true, nil
	} else {
		return false, nil
	}
}

func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) {
	subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)

	closedAddendum := ""
	if matcher.channelClosed {
		closedAddendum = " The channel is closed."
	}

	if hasSubMatcher {
		if matcher.receivedValue.IsValid() {
			return subMatcher.FailureMessage(matcher.receivedValue.Interface())
		}
		return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
	} else {
		return format.Message(actual, "to receive something."+closedAddendum)
	}
}

func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) {
	subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)

	closedAddendum := ""
	if matcher.channelClosed {
		closedAddendum = " The channel is closed."
	}

	if hasSubMatcher {
		if matcher.receivedValue.IsValid() {
			return subMatcher.NegatedFailureMessage(matcher.receivedValue.Interface())
		}
		return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
	} else {
		return format.Message(actual, "not to receive anything."+closedAddendum)
	}
}

func (matcher *ReceiveMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
	if !isChan(actual) {
		return false
	}

	return !matcher.channelClosed
}
