/*
 * Copyright (c) 2008, Edward Yakop. All Rights Reserved.
 * Copyright (c) 2008, Michael Hunger. All Rights Reserved.
 * Copyright (c) 2008, Niclas Hedhman. All Rights Reserved.
 * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
 * Copyright (c) 2013, Paul Merlin. All Rights Reserved.
 *
 * 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.test.entity;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.apache.zest.api.association.Association;
import org.apache.zest.api.association.ManyAssociation;
import org.apache.zest.api.association.NamedAssociation;
import org.apache.zest.api.common.Optional;
import org.apache.zest.api.common.UseDefaults;
import org.apache.zest.api.entity.EntityBuilder;
import org.apache.zest.api.entity.EntityComposite;
import org.apache.zest.api.injection.scope.Service;
import org.apache.zest.api.property.Property;
import org.apache.zest.api.unitofwork.ConcurrentEntityModificationException;
import org.apache.zest.api.unitofwork.NoSuchEntityException;
import org.apache.zest.api.unitofwork.UnitOfWork;
import org.apache.zest.api.unitofwork.UnitOfWorkCompletionException;
import org.apache.zest.api.value.ValueBuilder;
import org.apache.zest.api.value.ValueComposite;
import org.apache.zest.bootstrap.AssemblyException;
import org.apache.zest.bootstrap.ModuleAssembly;
import org.apache.zest.spi.entitystore.EntityStore;
import org.apache.zest.spi.uuid.UuidIdentityGeneratorService;
import org.apache.zest.test.AbstractQi4jTest;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

/**
 * Abstract satisfiedBy with tests for the EntityStore interface.
 */
public abstract class AbstractEntityStoreTest
    extends AbstractQi4jTest
{

    @Service
    private EntityStore store;

    @Override
    public void assemble( ModuleAssembly module )
        throws AssemblyException
    {
        module.services( UuidIdentityGeneratorService.class );
        module.entities( TestEntity.class );
        module.values( TestValue.class, TestValue2.class, TjabbaValue.class );
        module.objects( getClass() );
    }

    @Before
    public void init()
    {
        module.injectTo( this );
    }

    @Override
    @After
    public void tearDown()
        throws Exception
    {
        super.tearDown();
    }

    protected TestEntity createEntity( UnitOfWork unitOfWork )
        throws UnitOfWorkCompletionException
    {
        // Create entity
        EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder( TestEntity.class );
        builder.instance().dateValue().set( new Date() );
        TestEntity instance = builder.newInstance();

        instance.name().set( "Test" );
        instance.intValue().set( 42 );
        instance.longValue().set( 42L );
        instance.doubleValue().set( 42D );
        instance.floatValue().set( 42F );
        instance.booleanValue().set( Boolean.TRUE );
        instance.bigIntegerValue().set( new BigInteger( "42" ) );
        instance.bigDecimalValue().set( new BigDecimal( "42" ) );
        instance.dateValue().set( new DateTime( "2020-03-04T13:24:35", UTC ).toDate() );
        instance.dateTimeValue().set( new DateTime( "2020-03-04T13:24:35", UTC ) );
        instance.localDateTimeValue().set( new LocalDateTime( "2020-03-04T13:23:00" ) );
        instance.localDateValue().set( new LocalDate( "2020-03-04" ) );
        instance.association().set( instance );

        ValueBuilder<Tjabba> valueBuilder4 = module.newValueBuilder( Tjabba.class );
        final Tjabba prototype4 = valueBuilder4.prototype();
        prototype4.bling().set( "BlinkLjus" );

        // Set value
        ValueBuilder<TestValue2> valueBuilder2 = module.newValueBuilder( TestValue2.class );
        TestValue2 prototype2 = valueBuilder2.prototype();
        prototype2.stringValue().set( "Bar" );
        Tjabba newValue = valueBuilder4.newInstance();
        prototype2.anotherValue().set( newValue );
        prototype2.anotherValue().set( newValue );

        ValueBuilder<Tjabba> valueBuilder3 = module.newValueBuilder( Tjabba.class );
        final Tjabba prototype3 = valueBuilder3.prototype();
        prototype3.bling().set( "Brakfis" );

        ValueBuilder<TestValue> valueBuilder1 = module.newValueBuilder( TestValue.class );
        TestValue prototype = valueBuilder1.prototype();
        prototype.enumProperty().set( TestEnum.VALUE3 );
        prototype.listProperty().get().add( "Foo" );

        prototype.valueProperty().set( valueBuilder2.newInstance() );
        prototype.tjabbaProperty().set( valueBuilder3.newInstance() );
        Map<String, String> mapValue = new HashMap<>( 1 );
        mapValue.put( "foo", "bar" );
        prototype.mapStringStringProperty().set( mapValue );
        instance.valueProperty().set( valueBuilder1.newInstance() );

        instance.manyAssociation().add( 0, instance );

        instance.namedAssociation().put( "foo", instance );
        instance.namedAssociation().put( "bar", instance );

        return instance;
    }

    @Test
    public void whenNewEntityThenCanFindEntityAndCorrectValues()
        throws Exception
    {
        UnitOfWork unitOfWork = module.newUnitOfWork();
        try
        {
            TestEntity instance = createEntity( unitOfWork );
            unitOfWork.complete();

            // Find entity
            unitOfWork = module.newUnitOfWork();
            instance = unitOfWork.get( instance );

            // Check state
            assertThat( "property 'intValue' has correct value",
                        instance.intValue().get(),
                        equalTo( 42 ) );

            assertThat( "property 'longValue' has correct value",
                        instance.longValue().get(),
                        equalTo( 42L ) );

            assertThat( "property 'doubleValue' has correct value",
                        instance.doubleValue().get(),
                        equalTo( 42D ) );

            assertThat( "property 'floatValue' has correct value",
                        instance.floatValue().get(),
                        equalTo( 42F ) );

            assertThat( "property 'booleanValue' has correct value",
                        instance.booleanValue().get(),
                        equalTo( Boolean.TRUE ) );

            assertThat( "property 'bigInteger' has correct value",
                        instance.bigIntegerValue().get(),
                        equalTo( new BigInteger( "42" ) ) );

            assertThat( "property 'bigDecimal' has correct value",
                        instance.bigDecimalValue().get(),
                        equalTo( new BigDecimal( "42" ) ) );

            assertThat( "property 'dateValue' has correct value",
                        instance.dateValue().get(),
                        equalTo( new DateTime( "2020-03-04T13:24:35", UTC ).toDate() ) );

            assertThat( "property 'dateTimeValue' has correct value",
                        instance.dateTimeValue().get(),
                        equalTo( new DateTime( "2020-03-04T13:24:35", UTC ) ) );

            assertThat( "property 'localDateTimeValue' has correct value",
                        instance.localDateTimeValue().get(),
                        equalTo( new LocalDateTime( "2020-03-04T13:23:00", UTC ) ) );

            assertThat( "property 'localDateValue' has correct value",
                        instance.localDateValue().get(),
                        equalTo( new LocalDate( "2020-03-04" ) ) );

            assertThat( "property 'name' has correct value",
                        instance.name().get(),
                        equalTo( "Test" ) );

            assertThat( "property 'unsetName' has correct value",
                        instance.unsetName().get(),
                        equalTo( null ) );

            assertThat( "property 'emptyName' has correct value",
                        instance.emptyName().get(),
                        equalTo( "" ) );

            assertThat( "property 'valueProperty.stringValue' has correct value",
                        instance.valueProperty().get().valueProperty().get().stringValue().get(),
                        equalTo( "Bar" ) );

            assertThat( "property 'valueProperty.listProperty' has correct value",
                        instance.valueProperty().get().listProperty().get().get( 0 ),
                        equalTo( "Foo" ) );

            assertThat( "property 'valueProperty.enumProperty' has correct value",
                        instance.valueProperty().get().enumProperty().get(),
                        equalTo( TestEnum.VALUE3 ) );

            assertThat( "property 'valueProperty.anotherValue.bling' has correct value",
                        instance.valueProperty().get().valueProperty().get().anotherValue().get().bling().get(),
                        equalTo( "BlinkLjus" ) );

            assertThat( "property 'valueProperty.tjabbaProperty.bling' has correct value",
                        instance.valueProperty().get().tjabbaProperty().get().bling().get(),
                        equalTo( "Brakfis" ) );

            Map<String, String> mapValue = new HashMap<>();
            mapValue.put( "foo", "bar" );
            assertThat( "property 'valueProperty.mapStringStringProperty' has correct value",
                        instance.valueProperty().get().mapStringStringProperty().get(),
                        equalTo( mapValue ) );

            assertThat( "association has correct value",
                        instance.association().get(),
                        equalTo( instance ) );

            assertThat( "manyAssociation has correct value",
                        instance.manyAssociation().iterator().next(),
                        equalTo( instance ) );

            assertThat( "namedAssociation has correct 'foo' value",
                        instance.namedAssociation().get( "foo" ),
                        equalTo( instance ) );

            assertThat( "namedAssociation has correct 'bar' value",
                        instance.namedAssociation().get( "bar" ),
                        equalTo( instance ) );

            unitOfWork.discard();
        }
        finally
        {
            unitOfWork.discard();
        }
    }

    @Test
    public void whenRemovedEntityThenCannotFindEntity()
        throws Exception
    {
        UnitOfWork unitOfWork = module.newUnitOfWork();
        TestEntity newInstance = createEntity( unitOfWork );
        String identity = newInstance.identity().get();
        unitOfWork.complete();

        // Remove entity
        unitOfWork = module.newUnitOfWork();
        TestEntity instance = unitOfWork.get( newInstance );
        unitOfWork.remove( instance );
        unitOfWork.complete();

        // Find entity
        unitOfWork = module.newUnitOfWork();
        try
        {
            unitOfWork.get( TestEntity.class, identity );
            fail( "Should not be able to find entity" );
        }
        catch( NoSuchEntityException e )
        {
            // Ok!
        }
        finally
        {
            unitOfWork.discard();
        }
    }

    @Test
    public void givenEntityIsNotModifiedWhenUnitOfWorkCompletesThenDontStoreState()
        throws UnitOfWorkCompletionException
    {
        TestEntity testEntity;
        String version;
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder( TestEntity.class );

            testEntity = builder.newInstance();
            unitOfWork.complete();
        }
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            testEntity = unitOfWork.get( testEntity );
            version = spi.entityStateOf( testEntity ).version();

            unitOfWork.complete();
        }
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            testEntity = unitOfWork.get( testEntity );
            String newVersion = spi.entityStateOf( testEntity ).version();
            assertThat( "version has not changed", newVersion, equalTo( version ) );

            unitOfWork.complete();
        }
    }

    @Test
    public void givenPropertyIsModifiedWhenUnitOfWorkCompletesThenStoreState()
        throws UnitOfWorkCompletionException
    {
        TestEntity testEntity;
        String version;
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder( TestEntity.class );

            testEntity = builder.newInstance();
            unitOfWork.complete();
        }
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            testEntity = unitOfWork.get( testEntity );
            testEntity.name().set( "Rickard" );
            version = spi.entityStateOf( testEntity ).version();

            unitOfWork.complete();
        }
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            testEntity = unitOfWork.get( testEntity );
            String newVersion = spi.entityStateOf( testEntity ).version();
            assertThat( "version has changed", newVersion, not( equalTo( version ) ) );

            unitOfWork.complete();
        }
    }

    @Test
    public void givenManyAssociationIsModifiedWhenUnitOfWorkCompletesThenStoreState()
        throws UnitOfWorkCompletionException
    {
        TestEntity testEntity;
        String version;
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder( TestEntity.class );

            testEntity = builder.newInstance();
            unitOfWork.complete();
        }
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            testEntity = unitOfWork.get( testEntity );
            testEntity.manyAssociation().add( 0, testEntity );
            version = spi.entityStateOf( testEntity ).version();

            unitOfWork.complete();
        }
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            testEntity = unitOfWork.get( testEntity );
            String newVersion = spi.entityStateOf( testEntity ).version();
            assertThat( "version has changed", newVersion, not( equalTo( version ) ) );

            unitOfWork.complete();
        }
    }

    @Test
    public void givenConcurrentUnitOfWorksWhenUoWCompletesThenCheckConcurrentModification()
        throws UnitOfWorkCompletionException
    {
        TestEntity testEntity;
        {
            UnitOfWork unitOfWork = module.newUnitOfWork();
            EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder( TestEntity.class );

            testEntity = builder.newInstance();
            unitOfWork.complete();
        }

        UnitOfWork unitOfWork1;
        TestEntity testEntity1;
        String version;
        {
            // Start working with Entity in one UoW
            unitOfWork1 = module.newUnitOfWork();
            testEntity1 = unitOfWork1.get( testEntity );
            version = spi.entityStateOf( testEntity1 ).version();
            if( version.isEmpty() )
            {
                unitOfWork1.discard();
                return; // Store doesn't track versions - no point in testing it
            }
            testEntity1.name().set( "A" );
            testEntity1.unsetName().set( "A" );
        }
        {
            // Start working with same Entity in another UoW, and complete it
            UnitOfWork unitOfWork = module.newUnitOfWork();
            TestEntity testEntity2 = unitOfWork.get( testEntity );
            assertThat( "version is correct", spi.entityStateOf( testEntity1 ).version(), equalTo( version ) );
            testEntity2.name().set( "B" );
            unitOfWork.complete();
        }
        {
            // Try to complete first UnitOfWork
            try
            {
                unitOfWork1.complete();
                fail( "Should have thrown concurrent modification exception" );
            }
            catch( ConcurrentEntityModificationException e )
            {
                unitOfWork1.discard();
            }
        }
        {
            // Check values
            unitOfWork1 = module.newUnitOfWork();
            testEntity1 = unitOfWork1.get( testEntity );
            assertThat( "property name has not been set", testEntity1.name().get(), equalTo( "B" ) );
            assertThat( "version is incorrect", spi.entityStateOf( testEntity1 ).version(),
                        not( equalTo( version ) ) );
            unitOfWork1.discard();
        }
    }

    @Test
    public void givenEntityStoredLoadedChangedWhenUnitOfWorkDiscardsThenDontStoreState()
        throws UnitOfWorkCompletionException
    {
        UnitOfWork unitOfWork = module.newUnitOfWork();
        try
        {
            String identity = createEntity( unitOfWork ).identity().get();
            unitOfWork.complete();

            unitOfWork = module.newUnitOfWork();
            TestEntity entity = unitOfWork.get( TestEntity.class, identity );
            assertThat( entity.intValue().get(), is( 42 ) );
            entity.intValue().set( 23 );
            unitOfWork.discard();

            unitOfWork = module.newUnitOfWork();
            entity = unitOfWork.get( TestEntity.class, identity );
            assertThat( entity.intValue().get(), is( 42 ) );
        }
        finally
        {
            unitOfWork.discard();
        }
    }

    public interface TestEntity
        extends EntityComposite
    {

        @UseDefaults
        Property<Integer> intValue();

        @UseDefaults
        Property<Long> longValue();

        @UseDefaults
        Property<Double> doubleValue();

        @UseDefaults
        Property<Float> floatValue();

        @UseDefaults
        Property<Boolean> booleanValue();

        @Optional
        Property<BigInteger> bigIntegerValue();

        @Optional
        Property<BigDecimal> bigDecimalValue();

        @Optional
        Property<Date> dateValue();

        @Optional
        Property<DateTime> dateTimeValue();

        @Optional
        Property<LocalDateTime> localDateTimeValue();

        @Optional
        Property<LocalDate> localDateValue();

        @Optional
        Property<String> name();

        @Optional
        Property<String> unsetName();

        @UseDefaults
        Property<String> emptyName();

        @Optional
        Property<TestValue> valueProperty();

        @Optional
        Association<TestEntity> association();

        @Optional
        Association<TestEntity> unsetAssociation();

        ManyAssociation<TestEntity> manyAssociation();

        NamedAssociation<TestEntity> namedAssociation();
    }

    public interface TjabbaValue
        extends Tjabba, ValueComposite
    {
    }

    public interface Tjabba
    {

        Property<String> bling();
    }

    public interface TestValue
        extends ValueComposite
    {

        @UseDefaults
        Property<String> stringProperty();

        @UseDefaults
        Property<Integer> intProperty();

        @UseDefaults
        Property<TestEnum> enumProperty();

        @UseDefaults
        Property<List<String>> listProperty();

        @UseDefaults
        Property<Map<String, Tjabba>> mapProperty();

        Property<TestValue2> valueProperty();

        Property<Tjabba> tjabbaProperty();

        Property<Map<String, String>> mapStringStringProperty();
    }

    public interface TestValue2
        extends ValueComposite
    {

        Property<String> stringValue();

        Property<Tjabba> anotherValue();
    }

    public enum TestEnum
    {

        VALUE1, VALUE2, VALUE3
    }

}
