/*
 * Copyright 2006-2011 Niclas Hedhman.
 *
 * 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.apache.zest.library.alarm;

import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.junit.Test;
import org.apache.zest.api.entity.EntityBuilder;
import org.apache.zest.api.mixin.Mixins;
import org.apache.zest.api.service.ServiceComposite;
import org.apache.zest.api.unitofwork.UnitOfWork;
import org.apache.zest.api.value.ValueBuilder;
import org.apache.zest.bootstrap.AssemblyException;
import org.apache.zest.bootstrap.ModuleAssembly;
import org.apache.zest.test.AbstractQi4jTest;
import org.apache.zest.test.EntityTestAssembler;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class ExtendedAlarmModelTest
    extends AbstractQi4jTest
{

    @SuppressWarnings( { "unchecked" } )
    @Override
    public void assemble( ModuleAssembly module )
        throws AssemblyException
    {
        module.services( TestAlarmModel.class );
        module.services( AlarmSystemService.class );
        new EntityTestAssembler().assemble( module );
        module.entities( AlarmPointEntity.class );
        module.forMixin( AlarmHistory.class ).declareDefaults().maxSize().set( 10 );
        module.values( AlarmEvent.class );
        module.values( AlarmCategory.class );
        module.values( AlarmStatus.class );
    }

    @Mixins( ExtendedAlarmModelService.ExtendedAlarmModelMixin.class )
    public interface TestAlarmModel
        extends AlarmModel, ServiceComposite
    {
    }

    @Override
    public void setUp()
        throws Exception
    {
        super.setUp();
        module.newUnitOfWork();
    }

    @Override
    public void tearDown()
        throws Exception
    {
        UnitOfWork uow = module.currentUnitOfWork();
        if( uow != null )
        {
            uow.discard();
        }
        super.tearDown();
    }

    @Test
    public void testDescription()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        boolean test1 = provider.modelDescription().toLowerCase().contains( "normal" );
        boolean test2 = provider.modelDescription().toLowerCase().contains( "activated" );
        boolean test3 = provider.modelDescription().toLowerCase().contains( "deactivated" );
        boolean test4 = provider.modelDescription().toLowerCase().contains( "acknowledged" );
        boolean test5 = provider.modelDescription().toLowerCase().contains( "activation" );
        boolean test6 = provider.modelDescription().toLowerCase().contains( "deactivation" );
        boolean test7 = provider.modelDescription().toLowerCase().contains( "acknowledge" );
        boolean test8 = provider.modelDescription().toLowerCase().contains( "block" );
        boolean test9 = provider.modelDescription().toLowerCase().contains( "unblock" );
        boolean test10 = provider.modelDescription().toLowerCase().contains( "disable" );
        boolean test11 = provider.modelDescription().toLowerCase().contains( "enable" );
        assertTrue( test1 && test2 && test3 && test4 && test5 && test6 && test7 && test8 && test9 && test10 && test11 );

        Locale english = new Locale( "en" );
        test1 = provider.modelDescription( english ).toLowerCase().contains( "normal" );
        test2 = provider.modelDescription( english ).toLowerCase().contains( "activated" );
        test3 = provider.modelDescription( english ).toLowerCase().contains( "deactivated" );
        test4 = provider.modelDescription( english ).toLowerCase().contains( "acknowledged" );
        test5 = provider.modelDescription( english ).toLowerCase().contains( "activation" );
        test6 = provider.modelDescription( english ).toLowerCase().contains( "deactivation" );
        test7 = provider.modelDescription( english ).toLowerCase().contains( "acknowledge" );
        test8 = provider.modelDescription( english ).toLowerCase().contains( "block" );
        test9 = provider.modelDescription( english ).toLowerCase().contains( "unblock" );
        test10 = provider.modelDescription( english ).toLowerCase().contains( "disable" );
        test11 = provider.modelDescription( english ).toLowerCase().contains( "enable" );
        assertTrue( test1 && test2 && test3 && test4 && test5 && test6 && test7 && test8 && test9 && test10 && test11 );
    }

    @Test
    public void testTriggers()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );
        List<String> triggers = provider.alarmTriggers();
        assertEquals( 7, triggers.size() );
        int result = 0;
        for( String trigger : triggers )
        {
            if( AlarmPoint.TRIGGER_ACTIVATE.equals( trigger ) )
            {
                result |= 1;
            }
            if( AlarmPoint.TRIGGER_DEACTIVATE.equals( trigger ) )
            {
                result |= 2;
            }
            if( AlarmPoint.TRIGGER_ACKNOWLEDGE.equals( trigger ) )
            {
                result |= 4;
            }
            if( AlarmPoint.TRIGGER_BLOCK.equals( trigger ) )
            {
                result |= 8;
            }
            if( AlarmPoint.TRIGGER_UNBLOCK.equals( trigger ) )
            {
                result |= 16;
            }
            if( AlarmPoint.TRIGGER_DISABLE.equals( trigger ) )
            {
                result |= 32;
            }
            if( AlarmPoint.TRIGGER_ENABLE.equals( trigger ) )
            {
                result |= 64;
            }
        }
        assertEquals( 127, result );
        assertEquals( AlarmPoint.STATUS_NORMAL, underTest.currentStatus().name( null ) );
    }

    @Test
    public void testStateChangeFromNormal()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmPoint alarm = createAlarm( "Another 1" );
        AlarmEvent event1 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACTIVATE );
        assertEquals( AlarmPoint.EVENT_ACTIVATION, event1.systemName().get() );

        alarm = createAlarm( "Another 2" );
        AlarmEvent event2 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DEACTIVATE );
        assertNull( event2 );

        alarm = createAlarm( "Another 3" );
        AlarmEvent event3 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACKNOWLEDGE );
        assertNull( event3 );

        alarm = createAlarm( "Another 4" );
        AlarmEvent event4 = provider.evaluate( alarm, AlarmPoint.TRIGGER_BLOCK );
        assertEquals( AlarmPoint.EVENT_BLOCKING, event4.systemName().get() );

        alarm = createAlarm( "Another 5" );
        AlarmEvent event5 = provider.evaluate( alarm, AlarmPoint.TRIGGER_UNBLOCK );
        assertNull( event5 );

        alarm = createAlarm( "Another 6" );
        AlarmEvent event6 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DISABLE );
        assertEquals( AlarmPoint.EVENT_DISABLING, event6.systemName().get() );

        alarm = createAlarm( "Another 7" );
        AlarmEvent event7 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ENABLE );
        assertNull( event7 );
    }

    @Test
    public void testStateChangeFromActivated()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmPoint alarm = createAlarm( "Another 1" );
        alarm.activate();

        AlarmEvent event1 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACTIVATE );
        assertNull( event1 );

        alarm = createAlarm( "Another 2" );
        alarm.activate();
        AlarmEvent event2 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DEACTIVATE );
        assertEquals( AlarmPoint.EVENT_DEACTIVATION, event2.systemName().get() );

        alarm = createAlarm( "Another 3" );
        alarm.activate();
        AlarmEvent event3 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACKNOWLEDGE );
        assertEquals( AlarmPoint.EVENT_ACKNOWLEDGEMENT, event3.systemName().get() );

        alarm = createAlarm( "Another 4" );
        alarm.activate();
        AlarmEvent event4 = provider.evaluate( alarm, AlarmPoint.TRIGGER_BLOCK );
        assertEquals( AlarmPoint.EVENT_BLOCKING, event4.systemName().get() );

        alarm = createAlarm( "Another 5" );
        alarm.activate();
        AlarmEvent event5 = provider.evaluate( alarm, AlarmPoint.TRIGGER_UNBLOCK );
        assertNull( event5 );

        alarm = createAlarm( "Another 6" );
        alarm.activate();
        AlarmEvent event6 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DISABLE );
        assertEquals( AlarmPoint.EVENT_DISABLING, event6.systemName().get() );

        alarm = createAlarm( "Another 7" );
        alarm.activate();
        AlarmEvent event7 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ENABLE );
        assertNull( event7 );
    }

    @Test
    public void testStateChangeFromAcknowledged()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmPoint alarm = createAlarm( "Another 1" );
        alarm.activate();
        alarm.acknowledge();

        AlarmEvent event1 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACTIVATE );
        assertNull( event1 );

        alarm = createAlarm( "Another 2" );
        alarm.activate();
        alarm.acknowledge();
        AlarmEvent event2 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DEACTIVATE );
        assertEquals( AlarmPoint.EVENT_DEACTIVATION, event2.systemName().get() );

        alarm = createAlarm( "Another 3" );
        alarm.activate();
        alarm.acknowledge();
        AlarmEvent event3 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACKNOWLEDGE );
        assertNull( event3 );

        alarm = createAlarm( "Another 4" );
        alarm.activate();
        alarm.acknowledge();
        AlarmEvent event4 = provider.evaluate( alarm, AlarmPoint.TRIGGER_BLOCK );
        assertEquals( AlarmPoint.EVENT_BLOCKING, event4.systemName().get() );

        alarm = createAlarm( "Another 5" );
        alarm.activate();
        alarm.acknowledge();
        AlarmEvent event5 = provider.evaluate( alarm, AlarmPoint.TRIGGER_UNBLOCK );
        assertNull( event5 );

        alarm = createAlarm( "Another 6" );
        alarm.activate();
        alarm.acknowledge();
        AlarmEvent event6 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DISABLE );
        assertEquals( AlarmPoint.EVENT_DISABLING, event6.systemName().get() );

        alarm = createAlarm( "Another 7" );
        alarm.activate();
        alarm.acknowledge();
        AlarmEvent event7 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ENABLE );
        assertNull( event7 );
    }

    @Test
    public void testStateChangeFromDeactivated()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmPoint alarm = createAlarm( "Another 1" );
        alarm.activate();
        alarm.deactivate();
        AlarmEvent event1 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACTIVATE );
        assertEquals( AlarmPoint.EVENT_ACTIVATION, event1.systemName().get() );

        alarm = createAlarm( "Another 2" );
        alarm.activate();
        alarm.deactivate();
        AlarmEvent event2 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DEACTIVATE );
        assertNull( event2 );

        alarm = createAlarm( "Another 3" );
        alarm.activate();
        alarm.deactivate();
        AlarmEvent event3 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACKNOWLEDGE );
        assertEquals( AlarmPoint.EVENT_ACKNOWLEDGEMENT, event3.systemName().get() );

        alarm = createAlarm( "Another 4" );
        alarm.activate();
        alarm.deactivate();
        AlarmEvent event4 = provider.evaluate( alarm, AlarmPoint.TRIGGER_BLOCK );
        assertEquals( AlarmPoint.EVENT_BLOCKING, event4.systemName().get() );

        alarm = createAlarm( "Another 5" );
        alarm.activate();
        alarm.deactivate();
        AlarmEvent event5 = provider.evaluate( alarm, AlarmPoint.TRIGGER_UNBLOCK );
        assertNull( event5 );

        alarm = createAlarm( "Another 6" );
        alarm.activate();
        alarm.deactivate();
        AlarmEvent event6 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DISABLE );
        assertEquals( AlarmPoint.EVENT_DISABLING, event6.systemName().get() );

        alarm = createAlarm( "Another 7" );
        alarm.activate();
        alarm.deactivate();
        AlarmEvent event7 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ENABLE );
        assertNull( event7 );
    }

    @Test
    public void testStateChangeFromBlocked()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmPoint alarm = createAlarm( "Another 1" );
        alarm.activate();
        alarm.trigger( "block" );
        AlarmEvent event1 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACTIVATE );
        assertNull( event1 );

        alarm = createAlarm( "Another 2" );
        alarm.activate();
        alarm.trigger( "block" );
        AlarmEvent event2 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DEACTIVATE );
        assertNull( event2 );

        alarm = createAlarm( "Another 3" );
        alarm.activate();
        alarm.trigger( "block" );
        AlarmEvent event3 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACKNOWLEDGE );
        assertNull( event3 );

        alarm = createAlarm( "Another 4" );
        alarm.activate();
        alarm.trigger( "block" );
        AlarmEvent event4 = provider.evaluate( alarm, AlarmPoint.TRIGGER_BLOCK );
        assertNull( event4 );

        alarm = createAlarm( "Another 5" );
        alarm.activate();
        alarm.trigger( "block" );
        AlarmEvent event5 = provider.evaluate( alarm, AlarmPoint.TRIGGER_UNBLOCK );
        assertEquals( AlarmPoint.EVENT_UNBLOCKING, event5.systemName().get() );

        alarm = createAlarm( "Another 6" );
        alarm.activate();
        alarm.trigger( "block" );
        AlarmEvent event6 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DISABLE );
        assertEquals( AlarmPoint.EVENT_DISABLING, event6.systemName().get() );

        alarm = createAlarm( "Another 7" );
        alarm.activate();
        alarm.trigger( "block" );
        AlarmEvent event7 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ENABLE );
        assertNull( event7 );
    }

    @Test
    public void testStateChangeFromDisabled()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmPoint alarm = createAlarm( "Another 1" );
        alarm.activate();
        alarm.trigger( "disable" );
        AlarmEvent event1 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACTIVATE );
        assertNull( event1 );

        alarm = createAlarm( "Another 2" );
        alarm.activate();
        alarm.trigger( "disable" );
        AlarmEvent event2 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DEACTIVATE );
        assertNull( event2 );

        alarm = createAlarm( "Another 3" );
        alarm.activate();
        alarm.trigger( "disable" );
        AlarmEvent event3 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ACKNOWLEDGE );
        assertNull( event3 );

        alarm = createAlarm( "Another 4" );
        alarm.activate();
        alarm.trigger( "disable" );
        AlarmEvent event4 = provider.evaluate( alarm, AlarmPoint.TRIGGER_BLOCK );
        assertNull( event4 );

        alarm = createAlarm( "Another 5" );
        alarm.activate();
        alarm.trigger( "disable" );
        AlarmEvent event5 = provider.evaluate( alarm, AlarmPoint.TRIGGER_UNBLOCK );
        assertNull( event5 );

        alarm = createAlarm( "Another 6" );
        alarm.activate();
        alarm.trigger( "disable" );
        AlarmEvent event6 = provider.evaluate( alarm, AlarmPoint.TRIGGER_DISABLE );
        assertNull( event6 );

        alarm = createAlarm( "Another 7" );
        alarm.activate();
        alarm.trigger( "disable" );
        AlarmEvent event7 = provider.evaluate( alarm, AlarmPoint.TRIGGER_ENABLE );
        assertEquals( AlarmPoint.EVENT_ENABLING, event7.systemName().get() );
    }

    @Test
    public void testIllegalTrigger()
        throws Exception
    {
        try
        {
            AlarmModel provider = module.findService( AlarmModel.class ).get();
            AlarmPoint underTest = createAlarm( "Test AlarmPoint" );
            provider.evaluate( underTest, "my-trigger" );
            fail( "IllegalArgumentException not thrown." );
        }
        catch( IllegalArgumentException e )
        {
            // Expected.
        }
    }

    @Test
    public void testNormalToActivated()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );
        underTest.activate();
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_NORMAL, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_ACTIVATED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testActivatedToDeactivated()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );
        underTest.activate();
        underTest.deactivate();
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_DEACTIVATED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testActivatedToAcknowledged()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.acknowledge();
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_ACKNOWLEDGED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testDeactivatedToNormal()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.deactivate();
        underTest.acknowledge();
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_DEACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_NORMAL, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testAcknowledgedToNormal()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.acknowledge();
        underTest.deactivate();
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACKNOWLEDGED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_NORMAL, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testDisabledToNormal()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.trigger( "disable" );
        underTest.trigger( "enable" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_DISABLED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_NORMAL, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testBlockedToNormal()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.trigger( "block" );
        underTest.trigger( "unblock" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_BLOCKED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_NORMAL, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testNormalToBlocked()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.trigger( "block" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_NORMAL, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_BLOCKED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testActivatedToBlocked()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.trigger( "block" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_BLOCKED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testDeactivatedToBlocked()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.deactivate();
        underTest.trigger( "block" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_DEACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_BLOCKED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testAcknowledgedToBlocked()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.acknowledge();
        underTest.trigger( "block" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACKNOWLEDGED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_BLOCKED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testNormalToDisabled()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.trigger( "disable" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_NORMAL, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_DISABLED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testActivatedToDisabled()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.trigger( "disable" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_DISABLED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testDeactivatedToDisabled()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.deactivate();
        underTest.trigger( "disable" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_DEACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_DISABLED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testAcknowledgedToDisabled()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.acknowledge();
        underTest.trigger( "disable" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACKNOWLEDGED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_DISABLED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testBlockedToDisabled()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.trigger( "block" );
        underTest.trigger( "disable" );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_BLOCKED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_DISABLED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testDisabledToBlocked()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.activate();
        underTest.trigger( "disable" );
        underTest.trigger( "block" );       // This trigger should be ignored.
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_DISABLED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testConditionChanges1()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.updateCondition( false );
        AlarmEvent event = underTest.history().lastEvent();
        assertNull( "Generated an event but should have not.", event );
    }

    @Test
    public void testConditionChanges2()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.updateCondition( true );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_NORMAL, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_ACTIVATED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testConditionChanges3()
        throws Exception
    {
        AlarmPoint underTest = createAlarm( "Test AlarmPoint" );

        underTest.updateCondition( true );
        underTest.updateCondition( false );
        AlarmEvent event = underTest.history().lastEvent();

        AlarmStatus oldstate = event.oldStatus().get();
        assertEquals( AlarmPoint.STATUS_ACTIVATED, oldstate.name( null ) );

        AlarmStatus newstate = event.newStatus().get();
        assertEquals( AlarmPoint.STATUS_DEACTIVATED, newstate.name( null ) );

        AlarmPoint eventalarm = getAlarm( event.alarmIdentity().get() );
        assertEquals( underTest, eventalarm );
    }

    @Test
    public void testComputeCondition()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmStatus s1 = createStatus( AlarmPoint.STATUS_NORMAL );
        assertFalse( provider.computeCondition( s1 ) );
        AlarmStatus s2 = createStatus( AlarmPoint.STATUS_ACTIVATED );
        assertTrue( provider.computeCondition( s2 ) );
        AlarmStatus s3 = createStatus( AlarmPoint.STATUS_DEACTIVATED );
        assertFalse( provider.computeCondition( s3 ) );
        AlarmStatus s4 = createStatus( AlarmPoint.STATUS_ACKNOWLEDGED );
        assertTrue( provider.computeCondition( s4 ) );

        AlarmStatus s5 = createStatus( AlarmPoint.STATUS_DISABLED );
        assertFalse( provider.computeCondition( s5 ) );
        AlarmStatus s6 = createStatus( AlarmPoint.STATUS_BLOCKED );
        assertFalse( provider.computeCondition( s6 ) );
        AlarmStatus s7 = createStatus( AlarmPoint.STATUS_REACTIVATED );
        assertTrue( provider.computeCondition( s7 ) );
    }

    @Test
    public void testComputeTriggerNormal()
        throws Exception
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmStatus status = createStatus( AlarmPoint.STATUS_NORMAL );
        String trigger1 = provider.computeTrigger( status, true );
        String trigger2 = provider.computeTrigger( status, false );
        assertEquals( AlarmPoint.TRIGGER_ACTIVATE, trigger1 );
        assertEquals( null, trigger2 );
    }

    @Test
    public void testComputeTriggerActivated()
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmStatus status = createStatus( AlarmPoint.STATUS_ACTIVATED );
        String trigger1 = provider.computeTrigger( status, true );
        String trigger2 = provider.computeTrigger( status, false );
        assertEquals( null, trigger1 );
        assertEquals( AlarmPoint.TRIGGER_DEACTIVATE, trigger2 );
    }

    @Test
    public void testComputeTRiggerDeactivated()
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmStatus status = createStatus( AlarmPoint.STATUS_DEACTIVATED );
        String trigger1 = provider.computeTrigger( status, true );
        String trigger2 = provider.computeTrigger( status, false );
        assertEquals( AlarmPoint.TRIGGER_ACTIVATE, trigger1 );
        assertEquals( null, trigger2 );
    }

    @Test
    public void testComputeTriggerAcknowledged()
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmStatus status = createStatus( AlarmPoint.STATUS_ACKNOWLEDGED );
        String trigger1 = provider.computeTrigger( status, true );
        String trigger2 = provider.computeTrigger( status, false );
        assertEquals( null, trigger1 );
        assertEquals( AlarmPoint.TRIGGER_DEACTIVATE, trigger2 );
    }

    @Test
    public void testComputeTriggerReactivated()
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmStatus status = createStatus( AlarmPoint.STATUS_REACTIVATED );
        String trigger1 = provider.computeTrigger( status, true );
        String trigger2 = provider.computeTrigger( status, false );
        assertEquals( null, trigger1 );
        assertEquals( AlarmPoint.TRIGGER_DEACTIVATE, trigger2 );
    }

    @Test
    public void testComputeTriggerBlocked()
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmStatus status = createStatus( AlarmPoint.STATUS_BLOCKED );
        String trigger1 = provider.computeTrigger( status, true );
        String trigger2 = provider.computeTrigger( status, false );
        assertEquals( null, trigger1 );
        assertEquals( null, trigger2 );
    }

    @Test
    public void testComputeTriggerDisabled()
    {
        AlarmModel provider = module.findService( AlarmModel.class ).get();
        AlarmStatus status = createStatus( AlarmPoint.STATUS_DISABLED );
        String trigger1 = provider.computeTrigger( status, true );
        String trigger2 = provider.computeTrigger( status, false );
        assertEquals( null, trigger1 );
        assertEquals( null, trigger2 );
    }

    private AlarmPoint createAlarm( String name )
    {
        UnitOfWork uow = module.currentUnitOfWork();
        EntityBuilder<AlarmPoint> builder = uow.newEntityBuilder( AlarmPoint.class );
        builder.instance().category().set( createCategory( "Testing" ) );
        AlarmPoint.AlarmState state = builder.instanceFor( AlarmPoint.AlarmState.class );
        state.currentStatus().set( createStatus( AlarmPoint.STATUS_NORMAL ) );
        state.description().set( "Test Description" );
        state.systemName().set( name );
        return builder.newInstance();
    }

    private AlarmCategory createCategory( String name )
    {
        ValueBuilder<AlarmCategory> builder = module.newValueBuilder( AlarmCategory.class );
        builder.prototype().name().set( name );
        return builder.newInstance();
    }

    private AlarmPoint getAlarm( String identity )
    {
        UnitOfWork uow = module.currentUnitOfWork();
        return uow.get( AlarmPoint.class, identity );
    }

    private AlarmStatus createStatus( String status )
    {
        ValueBuilder<AlarmStatus> builder = module.newValueBuilder( AlarmStatus.class );
        AlarmStatus.State statePrototype = builder.prototypeFor( AlarmStatus.State.class );
        statePrototype.name().set( status );
        statePrototype.creationDate().set( new Date() );
        return builder.newInstance();
    }
}
