/*
 * Copyright (c) 2008, Rickard Öberg. 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.qi4j.spi.entitystore;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.qi4j.api.Qi4j;
import org.qi4j.api.concern.ConcernOf;
import org.qi4j.api.entity.EntityDescriptor;
import org.qi4j.api.entity.EntityReference;
import org.qi4j.api.injection.scope.Structure;
import org.qi4j.api.injection.scope.This;
import org.qi4j.api.usecase.Usecase;
import org.qi4j.spi.entity.EntityState;
import org.qi4j.spi.module.ModuleSpi;

/**
 * Concern that helps EntityStores do concurrent modification checks.
 * <p>
 * It caches the versions of state that it loads, and forgets them when
 * the state is committed. For normal operation this means that it does
 * not have to go down to the underlying store to get the current version.
 * Whenever there is a concurrent modification the store will most likely
 * have to check with the underlying store what the current version is.
 * </p>
 */
public abstract class ConcurrentModificationCheckConcern
    extends ConcernOf<EntityStore>
    implements EntityStore
{
    @This
    private EntityStateVersions versions;

    @Structure
    private Qi4j api;

    @Override
    public EntityStoreUnitOfWork newUnitOfWork( Usecase usecase, ModuleSpi module, long currentTime )
    {
        final EntityStoreUnitOfWork uow = next.newUnitOfWork( usecase, module, currentTime );
        return new ConcurrentCheckingEntityStoreUnitOfWork( uow, api.dereference( versions ), module, currentTime );
    }

    private static class ConcurrentCheckingEntityStoreUnitOfWork
        implements EntityStoreUnitOfWork
    {
        private final EntityStoreUnitOfWork uow;
        private EntityStateVersions versions;
        private ModuleSpi module;
        private long currentTime;

        private List<EntityState> loaded = new ArrayList<>();

        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

        public ConcurrentCheckingEntityStoreUnitOfWork( EntityStoreUnitOfWork uow,
                                                        EntityStateVersions versions,
                                                        ModuleSpi module,
                                                        long currentTime
        )
        {
            this.uow = uow;
            this.versions = versions;
            this.module = module;
            this.currentTime = currentTime;
        }

        @Override
        public String identity()
        {
            return uow.identity();
        }

        @Override
        public long currentTime()
        {
            return uow.currentTime();
        }

        @Override
        public EntityState newEntityState( ModuleSpi module,
                                           EntityReference anIdentity,
                                           EntityDescriptor entityDescriptor
        )
            throws EntityStoreException
        {
            return uow.newEntityState( module, anIdentity, entityDescriptor );
        }

        @Override
        public StateCommitter applyChanges()
            throws EntityStoreException
        {
            lock.writeLock().lock();

            try
            {
                versions.checkForConcurrentModification( loaded, module, currentTime );

                final StateCommitter committer = uow.applyChanges();

                return new StateCommitter()
                {
                    @Override
                    public void commit()
                    {
                        committer.commit();
                        versions.forgetVersions( loaded );

                        lock.writeLock().unlock();
                    }

                    @Override
                    public void cancel()
                    {
                        committer.cancel();
                        versions.forgetVersions( loaded );

                        lock.writeLock().unlock();
                    }
                };
            }
            catch( EntityStoreException e )
            {
                lock.writeLock().unlock();
                throw e;
            }
        }

        @Override
        public void discard()
        {
            try
            {
                uow.discard();
            }
            finally
            {
                lock.writeLock().lock();

                try
                {
                    versions.forgetVersions( loaded );
                }
                finally
                {
                    lock.writeLock().unlock();
                }
            }
        }

        @Override
        public Usecase usecase()
        {
            return uow.usecase();
        }

        @SuppressWarnings( "DuplicateThrows" )
        @Override
        public EntityState entityStateOf( ModuleSpi module, EntityReference anIdentity )
            throws EntityStoreException, EntityNotFoundException
        {
            lock.readLock().lock();

            try
            {
                EntityState entityState = uow.entityStateOf( module, anIdentity );
                versions.rememberVersion( entityState.identity(), entityState.version() );
                loaded.add( entityState );
                return entityState;
            }
            finally
            {
                lock.readLock().unlock();
            }
        }
    }
}
