/*
 * JBoss, Home of Professional Open Source
 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.test.managed.factory.test;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Properties;

import javax.management.ObjectName;

import org.jboss.managed.api.ManagedObject;
import org.jboss.managed.api.ManagedProperty;
import org.jboss.managed.api.annotation.DefaultValueBuilderFactory;
import org.jboss.metatype.api.types.SimpleMetaType;
import org.jboss.metatype.api.values.MetaValue;
import org.jboss.metatype.api.values.PropertiesMetaValue;
import org.jboss.metatype.api.values.SimpleValue;
import org.jboss.metatype.api.values.SimpleValueSupport;
import org.jboss.metatype.plugins.types.ObjectNameTypeBuilder;
import org.jboss.metatype.plugins.values.mappers.PropertiesCompositeObjectNameMetaMapper;
import org.jboss.test.managed.factory.AbstractManagedObjectFactoryTest;
import org.jboss.test.managed.factory.support.defaults.DefaultsBean;

/**
 * Tests of specifying defaults on managed properties
 * @author Scott.Stark@jboss.org
 * @version $Revision: 87524 $
 */
public class PropertyDefaultsUnitTestCase extends AbstractManagedObjectFactoryTest
{

   public PropertyDefaultsUnitTestCase(String name)
   {
      super(name);
   }

   public void testFloatDefaults()
      throws Exception
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);

      // Test the temperature constraints
      ManagedProperty temperature = managedObject.getProperty("temperature");
      SimpleValue defaultValue = (SimpleValue) temperature.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("temperature default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(60f));
      assertTrue("temperature == 60; "+compare, compare == 0);

      ManagedProperty pi = managedObject.getProperty("pi");
      defaultValue = (SimpleValue) pi.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("pi default: "+defaultValue);
      compare = defaultValue.compareTo(SimpleValueSupport.wrap(3.14f));
      assertTrue("pi == 3.14; "+compare, compare == 0);
   }
   /**
    * Test default value for Double property types
    */
   public void testDoubleDefaults()
      throws Exception
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
   
      // Test the temperature constraints
      ManagedProperty temperature = managedObject.getProperty("temperatureD");
      SimpleValue defaultValue = (SimpleValue) temperature.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("temperature default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(60.5));
      assertTrue("temperature == 60; "+compare, compare == 0);
   
      ManagedProperty pi = managedObject.getProperty("piD");
      defaultValue = (SimpleValue) pi.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("pi default: "+defaultValue);
      compare = defaultValue.compareTo(SimpleValueSupport.wrap(3.14159265358979));
      assertTrue("pi == 3.14159265358979 "+compare, compare == 0);
   }
   /**
    * Test default value for Long property types
    */
   public void testLongDefaults()
      throws Exception
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
   
      // Test the temperature constraints
      ManagedProperty temperature = managedObject.getProperty("propLong");
      SimpleValue defaultValue = (SimpleValue) temperature.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("propLong default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(123456789l));
      assertTrue("propLong == 123456789; "+compare, compare == 0);
   
      ManagedProperty pi = managedObject.getProperty("propLongPrimitive");
      defaultValue = (SimpleValue) pi.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("propLongPrimitive default: "+defaultValue);
      compare = defaultValue.compareTo(SimpleValueSupport.wrap(123456789l));
      assertTrue("propLongPrimitive == 123456789 "+compare, compare == 0);
   }
   /**
    * Test default value for String property types
    */
   public void testStringDefaults()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty month = managedObject.getProperty("month");
      SimpleValue defaultValue = (SimpleValue) month.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("month default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap("JAN"));
      assertTrue("month == JAN; "+compare, compare == 0);
   }
   /**
    * Test default value for BigDecimal property types
    */
   public void testBigDecimalDefaults()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty month = managedObject.getProperty("propBD");
      SimpleValue defaultValue = (SimpleValue) month.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("propBD default: "+defaultValue);
      BigDecimal bd = new BigDecimal("123456789.987654321");
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(bd));
      assertTrue("propBD == 123456789.987654321; "+compare, compare == 0);
   }
   /**
    * Test default value for BigInteger property types
    */
   public void testBigIntegerDefaults()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty propBI = managedObject.getProperty("propBI");
      SimpleValue defaultValue = (SimpleValue) propBI.getDefaultValue();
      assertEquals(SimpleMetaType.BIGINTEGER, defaultValue.getMetaType());
      assertNotNull(defaultValue);
      getLog().debug("propBI default: "+defaultValue);
      BigInteger bd = new BigInteger("123456789987654321");
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(bd));
      assertEquals("propBI == 123456789987654321; "+compare, 0, compare);
   }

   /**
    * Test default value for Char property types
    */
   public void testCharDefaults()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty propCharPrimitive = managedObject.getProperty("propCharPrimitive");
      SimpleValue defaultValue = (SimpleValue) propCharPrimitive.getDefaultValue();
      assertNotNull(defaultValue);
      assertEquals(SimpleMetaType.CHARACTER_PRIMITIVE, defaultValue.getMetaType());
      getLog().debug("propCharPrimitive default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap('c'));
      assertEquals("propCharPrimitive == c; ", 0, compare);

      ManagedProperty propChar = managedObject.getProperty("propChar");
      defaultValue = (SimpleValue) propChar.getDefaultValue();
      assertNotNull(defaultValue);
      assertEquals(SimpleMetaType.CHARACTER, defaultValue.getMetaType());
      getLog().debug("propChar default: "+defaultValue);
      compare = defaultValue.compareTo(SimpleValueSupport.wrap(new Character('C')));
      assertTrue("propChar == c; "+compare, compare == 0);
   }

   /**
    * Test default value for Integer property types
    */
   public void testIntDefaults()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty day = managedObject.getProperty("day");
      SimpleValue defaultValue = (SimpleValue) day.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("day default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(1));
      assertTrue("day == 1; "+compare, compare == 0);

      ManagedProperty century = managedObject.getProperty("century");
      defaultValue = (SimpleValue) century.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("century default: "+defaultValue);
      compare = defaultValue.compareTo(SimpleValueSupport.wrap(2000));
      assertTrue("century == 2000; "+compare, compare == 0);
   }
   /**
    * Test default value for Byte property types
    */
   public void testByteDefaults()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty propByte = managedObject.getProperty("propByte");
      SimpleValue defaultValue = (SimpleValue) propByte.getDefaultValue();
      assertNotNull(defaultValue);
      assertEquals(SimpleMetaType.BYTE, defaultValue.getMetaType());
      getLog().debug("propByte default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(10));
      assertTrue("propByte == 1; "+compare, compare == 0);

      ManagedProperty propBytePrimitive = managedObject.getProperty("propBytePrimitive");
      defaultValue = (SimpleValue) propBytePrimitive.getDefaultValue();
      assertNotNull(defaultValue);
      assertEquals(SimpleMetaType.BYTE_PRIMITIVE, defaultValue.getMetaType());
      getLog().debug("propBytePrimitive default: "+defaultValue);
      compare = defaultValue.compareTo(SimpleValueSupport.wrap(10));
      assertEquals("propBytePrimitive == 10; ", 0, compare);
   }
   /**
    * Test default value for Short property types
    */
   public void testShortDefaults()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty dayOfYear = managedObject.getProperty("dayOfYear");
      SimpleValue defaultValue = (SimpleValue) dayOfYear.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("dayOfYear default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(1));
      assertTrue("dayOfYear == 1; "+compare, compare == 0);

      ManagedProperty propShortPrimitive = managedObject.getProperty("propShortPrimitive");
      defaultValue = (SimpleValue) propShortPrimitive.getDefaultValue();
      assertNotNull(defaultValue);
      assertEquals(SimpleMetaType.SHORT_PRIMITIVE, defaultValue.getMetaType());
      getLog().debug("propShortPrimitive default: "+defaultValue);
      compare = defaultValue.compareTo(SimpleValueSupport.wrap(1234));
      assertTrue("propShortPrimitive == 1234; "+compare, compare == 0);
   }
   /**
    * Test default value for Boolean property types
    */
   public void testBooleanDefaults()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty propBoolean = managedObject.getProperty("propBoolean");
      SimpleValue defaultValue = (SimpleValue) propBoolean.getDefaultValue();
      assertNotNull(defaultValue);
      assertEquals(SimpleMetaType.BOOLEAN, defaultValue.getMetaType());
      getLog().debug("propBoolean default: "+defaultValue);
      int compare = defaultValue.compareTo(SimpleValueSupport.wrap(Boolean.TRUE));
      assertTrue("propBoolean == true; "+compare, compare == 0);

      ManagedProperty propBooleanPrimitive = managedObject.getProperty("propBooleanPrimitive");
      defaultValue = (SimpleValue) propBooleanPrimitive.getDefaultValue();
      assertNotNull(defaultValue);
      assertEquals(SimpleMetaType.BOOLEAN_PRIMITIVE, defaultValue.getMetaType());
      getLog().debug("propBooleanPrimitive default: "+defaultValue);
      compare = defaultValue.compareTo(SimpleValueSupport.wrap(true));
      assertEquals("propBooleanPrimitive == true; ", 0, compare);
   }
   /**
    * Test default value for a Properties type
    */
   public void testPropertiesDefault()
      throws Exception
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty props = managedObject.getProperty("props");
      MetaValue defaultValue = props.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("props default: "+defaultValue);
      Properties expected = new Properties();
      expected.put("key1", "value1");
      expected.put("key2", "value2");
      assertEquals(expected, defaultValue);      
   }
   /**
    * Test default value for a Properties type with a DefaultValueBuilderFactory
    */
   public void testOverridenPropertiesDefault()
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty props = managedObject.getProperty("props2");
      MetaValue defaultValue = props.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("props default: "+defaultValue);
      Properties expected = new Properties();
      expected.put("key1", "props2-value1");
      expected.put("key2", "props2-value2");
      assertEquals(expected, defaultValue);   
   }
   /**
    * Test default value for a ObjectName type with SimpleMetaType.STRING type
    */
   public void testStringObjectNameDefault()
      throws Exception
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty nameAsString = managedObject.getProperty("nameAsString");
      MetaValue defaultValue = nameAsString.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("nameAsString default: "+defaultValue);
      MetaValue expected = SimpleValueSupport.wrap("domain1:key1=value1,key2=value2");
      assertEquals(expected, defaultValue);      
   }
   /**
    * Test default value for a ObjectName type with PropertiesMetaType
    */
   public void testPropertiesObjectNameDefault()
      throws Exception
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty nameAsProperties = managedObject.getProperty("nameAsProperties");
      MetaValue defaultValue = nameAsProperties.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("nameAsProperties default: "+defaultValue);
      Properties p = new Properties();
      p.setProperty("domain", "domain1");
      p.setProperty("key1", "value1");
      p.setProperty("key2", "value2");
      PropertiesMetaValue expected = new PropertiesMetaValue(p);
      assertEquals(expected, defaultValue);      
   }
   /**
    * Test default value for a ObjectName type with default meta type
    */
   public void testDefaultObjectNameDefault()
      throws Exception
   {
      DefaultsBean bean = new DefaultsBean();
      ManagedObject managedObject = super.initManagedObject(bean);
      ManagedProperty nameAsProperties = managedObject.getProperty("nameAsDefault");
      MetaValue defaultValue = nameAsProperties.getDefaultValue();
      assertNotNull(defaultValue);
      getLog().debug("nameAsProperties default: "+defaultValue);
      assertEquals(ObjectNameTypeBuilder.META_TYPE, defaultValue.getMetaType());
      PropertiesCompositeObjectNameMetaMapper mapper = new PropertiesCompositeObjectNameMetaMapper();
      MetaValue expected = mapper.createMetaValue(null, new ObjectName("domain1:key1=value1,key2=value2"));
      assertEquals(expected, defaultValue);      
   }
}
