// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gomock

import (
	
	
	
)

// callSet represents a set of expected calls, indexed by receiver and method
// name.
type callSet struct {
	// Calls that are still expected.
	expected map[callSetKey][]*Call
	// Calls that have been exhausted.
	exhausted map[callSetKey][]*Call
}

// callSetKey is the key in the maps in callSet
type callSetKey struct {
	receiver interface{}
	fname    string
}

func () *callSet {
	return &callSet{make(map[callSetKey][]*Call), make(map[callSetKey][]*Call)}
}

// Add adds a new expected call.
func ( callSet) ( *Call) {
	 := callSetKey{.receiver, .method}
	 := .expected
	if .exhausted() {
		 = .exhausted
	}
	[] = append([], )
}

// Remove removes an expected call.
func ( callSet) ( *Call) {
	 := callSetKey{.receiver, .method}
	 := .expected[]
	for ,  := range  {
		if  ==  {
			// maintain order for remaining calls
			.expected[] = append([:], [+1:]...)
			.exhausted[] = append(.exhausted[], )
			break
		}
	}
}

// FindMatch searches for a matching call. Returns error with explanation message if no call matched.
func ( callSet) ( interface{},  string,  []interface{}) (*Call, error) {
	 := callSetKey{, }

	// Search through the expected calls.
	 := .expected[]
	var  bytes.Buffer
	for ,  := range  {
		 := .matches()
		if  != nil {
			_, _ = fmt.Fprintf(&, "\n%v", )
		} else {
			return , nil
		}
	}

	// If we haven't found a match then search through the exhausted calls so we
	// get useful error messages.
	 := .exhausted[]
	for ,  := range  {
		if  := .matches();  != nil {
			_, _ = fmt.Fprintf(&, "\n%v", )
			continue
		}
		_, _ = fmt.Fprintf(
			&, "all expected calls for method %q have been exhausted", ,
		)
	}

	if len()+len() == 0 {
		_, _ = fmt.Fprintf(&, "there are no expected calls of the method %q for that receiver", )
	}

	return nil, errors.New(.String())
}

// Failures returns the calls that are not satisfied.
func ( callSet) () []*Call {
	 := make([]*Call, 0, len(.expected))
	for ,  := range .expected {
		for ,  := range  {
			if !.satisfied() {
				 = append(, )
			}
		}
	}
	return 
}