/*
 * Copyright 2009 the original author or authors.
 *
 * 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 org.spockframework.mock;

import java.util.ArrayList;
import java.util.List;

import org.codehaus.groovy.runtime.DefaultGroovyMethods;

import org.spockframework.util.TextUtil;

/**
 * Indicates that a required interaction has matched too many invocations.
 * 
 * @author Peter Niederwieser
 */
public class TooManyInvocationsError extends InteractionNotSatisfiedError {
  private final IMockInteraction interaction;
  private final IMockInvocation invocation;

  public TooManyInvocationsError(IMockInteraction interaction, IMockInvocation invocation) {
    this.interaction = interaction;
    this.invocation = invocation;
  }

  public IMockInteraction getInteraction() {
    return interaction;
  }

  public IMockInvocation getInvocation() {
    return invocation;
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("Too many invocations for:\n\n");
    int numInvoked = interaction.getAcceptedCount() + 1;
    builder.append(String.format("%s   (%d %s)\n\n",
        interaction, numInvoked, numInvoked == 1 ? "invocation" : "invocations"));
    builder.append(String.format("Last invocation: %s.%s(%s)\n", invocation.getMockObjectName(),
        invocation.getMethod().getName(), TextUtil.concat(toString(invocation.getArguments()), ", ")));
    return builder.toString();
  }

  private List<String> toString(List<Object> objects) {
    List<String> result = new ArrayList<String>();
    for (Object obj : objects) result.add(DefaultGroovyMethods.inspect(obj));
    return result;
  }
}

@@ -1058,33 +1058,37 @@
 IMockInvocation 
-i
+lastI
 nvocation;%0A%0A  pu
@@ -1162,17 +1162,21 @@
 ocation 
-i
+lastI
 nvocatio
@@ -1225,17 +1225,21 @@
    this.
-i
+lastI
 nvocatio
@@ -1242,17 +1242,21 @@
 ation = 
-i
+lastI
 nvocatio
@@ -1365,16 +1365,20 @@
 tion get
+Last
 Invocati
@@ -1395,17 +1395,21 @@
  return 
-i
+lastI
 nvocatio
@@ -1567,181 +1567,90 @@
     
-int numInvoked = interaction.getAcceptedCount() + 1;%0A    builder.append(String.format(%22%25s   (%25d %25s)
+builder.append(interaction);%0A    builder.append(%22
 %5Cn%5Cn%22
-,
+);
 %0A    
-    interaction, numInvoked, numInvoked == 1 ? %22invocation%22 : %22
+builder.append(%22Last 
 invo
@@ -1659,11 +1659,11 @@
 tion
-s%22)
+: %22
 );%0A 
@@ -1684,29 +1684,13 @@
 end(
-String.format(%22Last i
+lastI
 nvoc
@@ -1698,398 +1698,66 @@
 tion
-: %25s.%25s(%25s)%5Cn%22, invocation.getMockObjectName(),%0A        invocation.getMethod().getName(), TextUtil.concat(toString(invocation.getArguments()), %22, %22)));%0A    return builder.toString();%0A  %7D%0A%0A  private List%3CString%3E toString(List%3CObject%3E objects) %7B%0A    List%3CString%3E result = new ArrayList%3CString%3E();%0A    for (Object obj : objects) result.add(DefaultGroovyMethods.inspect(obj));%0A    return result
+);%0A    builder.append(%22%5Cn%22);%0A    return builder.toString()
 ;%0A  

improved string representation of TooManyInvocationsError