/* ===================================================================
 * RecipeBizTest.java
 * 
 * Created Oct 13, 2004 8:34:24 AM
 * 
 * Copyright (c) 2004 Matt Magoffin (spamsqr@msqr.us)
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation; either version 2 of 
 * the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
 * 02111-1307 USA
 * ===================================================================
 * $Id: RecipeBizTest.java 30 2009-05-04 01:53:34Z msqr $
 * ===================================================================
 */

package magoffin.matt.ieat.biz.test;

import java.util.List;

import magoffin.matt.ieat.AuthorizationException;
import magoffin.matt.ieat.biz.BizContext;
import magoffin.matt.ieat.biz.RecipeBiz;
import magoffin.matt.ieat.domain.Ingredient;
import magoffin.matt.ieat.domain.Recipe;
import magoffin.matt.ieat.domain.RecipeIngredient;
import magoffin.matt.ieat.domain.System;
import magoffin.matt.ieat.domain.Unit;
import magoffin.matt.ieat.domain.User;
import magoffin.matt.ieat.test.AbstractSpringEnabledTest;

/**
 * Test case for RecipeBiz.
 * 
 * @author Matt Magoffin (spamsqr@msqr.us)
 * @version $Revision: 30 $ $Date: 2009-05-04 13:53:34 +1200 (Mon, 04 May 2009) $
 */
public class RecipeBizTest extends AbstractSpringEnabledTest {
	
	private boolean flip = false;
	
	/**
	 * @return a random ingredient
	 */
	protected Ingredient getRandomIngredient() {
		List<Ingredient> l = getRecipeBiz().getAvailableIngredients();
		int rndIdx = (int)Math.round(Math.random()*l.size());
		return l.get(rndIdx);
	}
	
	/**
	 * Get a random unit for a given system.
	 * @param system the unit system
	 * @return unit
	 */
	protected Unit getRandomUnit(System system) {
		List<Unit> l = getRecipeBiz().getAvailableUnitsForSystem(system);
		int rndIdx = (int)Math.round(Math.random()*l.size());
		return l.get(rndIdx);
	}
	
	/**
	 * Get a test recipe ingredient for a given system.
	 * @param system the unit system
	 * @return the recipe ingredient
	 */
	protected RecipeIngredient getDummyRecipeIngredient(System system) {
		RecipeIngredient ri = getDomainObjectFactory().getRecipeIngredientInstance();
		ri.setQuantity((float)Math.random()*10.0f);
		double rand = Math.random();
		if ( rand > 0.5 ) {
			while ( true ) {
				Unit u = getRandomUnit(system);
				if ( flip ) {
					if ( u.getSystemId() == null ) {
						continue;
					}
				}
				ri.setUnit(u);
				break;
			}
			flip = !flip;
		}
		Ingredient ing = getRandomIngredient();
		ri.setIngredient(ing);
		return ri;
	}
	
	/**
	 * Test converting recipe from US to Metric.
	 * @throws AuthorizationException if auth error occurs
	 */
	@SuppressWarnings("unchecked")
	public void testConvertRecipeFromUSToMetric() throws AuthorizationException {
		Recipe r = getDummyRecipe();
		System us = getDomainObjectFactory().getSystemInstance();
		us.setSystemId(RecipeBiz.US_SYSTEM_ID);
		r.setSystem(us);

		// populate a random # of ingredients
		int maxIngredients = (int)Math.round(Math.random()*9) + 3;
		for ( int i = 0; i < maxIngredients; i++ ) {
			RecipeIngredient ri = getDummyRecipeIngredient(r.getSystem());
			r.getIngredient().add(ri);
		}
		
		RecipeBiz recipeBiz = getRecipeBiz();
		BizContext context = getBizContext();
		User u = context.getActingUser();
		try {
			// store user in back end
			u = getUserBiz().storeUser(u,context);
			
			// store recipe in back end
			r = recipeBiz.storeRecipe(r,context);
			
			if ( log.isDebugEnabled() ) {
				log.debug("Original recipe: " +debugRecipe(r));
			}
			
			// convert recipe
			Recipe converted = getRecipeBiz().convertRecipeSystem(r.getRecipeId(),RecipeBiz.METRIC_SYSTEM_ID);
			if ( log.isDebugEnabled() ) {
				log.debug("Converted recipe: " +debugRecipe(converted));
			}
		} finally {
			cleanOutRecipe(r);
			cleanOutUser(u);
		}
	}
	
	@SuppressWarnings("unchecked")
	private String debugRecipe(Recipe r) {
		StringBuilder buf = new StringBuilder();
		buf.append("Recipe ").append(r.getRecipeId()).append(": ").append(r.getName()).append("\n");
		for ( RecipeIngredient ri : (List<RecipeIngredient>)r.getIngredient() ) {
			buf.append("  ").append(ri.getQuantity());
			if ( ri.getUnit() != null ) {
				buf.append(" ").append(ri.getUnit().getAbbreviation());
			}
			buf.append(" ").append(ri.getIngredient().getName()).append("\n");
		}
		return buf.toString();
	}

}
