/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.ignite.internal.processors.cache.transactions;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.CacheWriteSynchronizationMode;
import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
import org.apache.ignite.internal.processors.cache.CacheStoppedException;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
import org.apache.ignite.internal.util.GridIntList;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;

import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC;

/**
 *
 */
public class IgniteTxImplicitSingleStateImpl extends IgniteTxLocalStateAdapter {
    /** */
    private GridCacheContext cacheCtx;

    /** Entry is stored as singleton list for performance optimization. */
    private List<IgniteTxEntry> entry;

    /** */
    private boolean init;

    /** */
    private boolean recovery;

    /** {@inheritDoc} */
    @Override public void addActiveCache(GridCacheContext ctx, boolean recovery, IgniteTxAdapter tx)
        throws IgniteCheckedException {
        assert cacheCtx == null : "Cache already set [cur=" + cacheCtx.name() + ", new=" + ctx.name() + ']';
        assert tx.local();

        cacheCtx = ctx;
        this.recovery = recovery;

        tx.activeCachesDeploymentEnabled(cacheCtx.deploymentEnabled());
    }

    /** {@inheritDoc} */
    @Nullable @Override public GridIntList cacheIds() {
        return  GridIntList.asList(cacheCtx.cacheId());
    }

    /** {@inheritDoc} */
    @Nullable @Override public GridCacheContext singleCacheContext(GridCacheSharedContext cctx) {
        return cacheCtx;
    }

    /** {@inheritDoc} */
    @Nullable @Override public Integer firstCacheId() {
        return cacheCtx != null ? cacheCtx.cacheId() : null;
    }

    /** {@inheritDoc} */
    @Override public void unwindEvicts(GridCacheSharedContext cctx) {
        if (entry == null || entry.isEmpty())
            return;

        assert entry.size() == 1;

        GridCacheContext ctx = cctx.cacheContext(entry.get(0).cacheId());

        if (ctx != null)
            CU.unwindEvicts(ctx);
    }

    /** {@inheritDoc} */
    @Override public void awaitLastFuture(GridCacheSharedContext ctx) {
        if (cacheCtx == null)
            return;

        cacheCtx.cache().awaitLastFut();
    }

    /** {@inheritDoc} */
    @Override public boolean implicitSingle() {
        return true;
    }

    /** {@inheritDoc} */
    @Override public IgniteCheckedException validateTopology(
        GridCacheSharedContext cctx,
        boolean read,
        GridDhtTopologyFuture topFut
    ) {
        if (cacheCtx == null)
            return null;

        Throwable err = topFut.validateCache(cacheCtx, recovery, read, null, entry);

        if (err != null) {
            return new IgniteCheckedException(
                "Failed to perform cache operation (cache topology is not valid): "
                    + U.maskName(cacheCtx.name()), err);
        }

        if (CU.affinityNodes(cacheCtx, topFut.topologyVersion()).isEmpty()) {
            return new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
                "partition nodes left the grid): " + cacheCtx.name());
        }

        return null;
    }

    /** {@inheritDoc} */
    @Override public CacheWriteSynchronizationMode syncMode(GridCacheSharedContext cctx) {
        return cacheCtx != null ? cacheCtx.config().getWriteSynchronizationMode() : FULL_ASYNC;
    }

    /** {@inheritDoc} */
    @Override public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut) {
        if (cacheCtx == null || cacheCtx.isLocal())
            return cctx.exchange().lastTopologyFuture();

        cacheCtx.topology().readLock();

        if (cacheCtx.topology().stopping()) {
            fut.onDone(new CacheStoppedException(cacheCtx.name()));

            return null;
        }

        return cacheCtx.topology().topologyVersionFuture();
    }

    /** {@inheritDoc} */
    @Override public void topologyReadUnlock(GridCacheSharedContext cctx) {
        if (cacheCtx == null || cacheCtx.isLocal())
            return;

        cacheCtx.topology().readUnlock();
    }

    /** {@inheritDoc} */
    @Override public boolean storeWriteThrough(GridCacheSharedContext cctx) {
        if (cacheCtx == null)
            return false;

        CacheStoreManager store = cacheCtx.store();

        return store.configured() && store.isWriteThrough();
    }

    /** {@inheritDoc} */
    @Override public boolean hasInterceptor(GridCacheSharedContext cctx) {
        GridCacheContext ctx0 = cacheCtx;

        return ctx0 != null && ctx0.config().getInterceptor() != null;
    }

    /** {@inheritDoc} */
    @Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
        if (cacheCtx == null)
            return null;

        CacheStoreManager store = cacheCtx.store();

        if (store.configured())
            return Collections.singleton(store);

        return null;
    }

    /** {@inheritDoc} */
    @Override public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit) {
        if (cacheCtx != null)
            onTxEnd(cacheCtx, tx, commit);
    }

    /** {@inheritDoc} */
    @Override public IgniteTxEntry entry(IgniteTxKey key) {
        if (entry != null && entry.get(0).txKey().equals(key))
            return entry.get(0);

        return null;
    }

    /** {@inheritDoc} */
    @Override public boolean hasWriteKey(IgniteTxKey key) {
        return entry != null && entry.get(0).txKey().equals(key);
    }

    /** {@inheritDoc} */
    @Override public Set<IgniteTxKey> readSet() {
        return Collections.emptySet();
    }

    /** {@inheritDoc} */
    @Override public Set<IgniteTxKey> writeSet() {
        if (entry != null) {
            Set<IgniteTxKey> set = new HashSet<>(3, 0.75f);

            set.add(entry.get(0).txKey());

            return set;
        }
        else
            return Collections.<IgniteTxKey>emptySet();
    }

    /** {@inheritDoc} */
    @Override public Collection<IgniteTxEntry> writeEntries() {
        return entry != null ? entry : Collections.<IgniteTxEntry>emptyList();
    }

    /** {@inheritDoc} */
    @Override public Collection<IgniteTxEntry> readEntries() {
        return Collections.emptyList();
    }

    /** {@inheritDoc} */
    @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
        return entry != null ? F.asMap(entry.get(0).txKey(), entry.get(0)) :
            Collections.<IgniteTxKey, IgniteTxEntry>emptyMap();
    }

    /** {@inheritDoc} */
    @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
        return Collections.emptyMap();
    }

    /** {@inheritDoc} */
    @Override public boolean empty() {
        return entry == null;
    }

    /** {@inheritDoc} */
    @Override public Collection<IgniteTxEntry> allEntries() {
        return entry != null ? entry : Collections.<IgniteTxEntry>emptyList();
    }

    /** {@inheritDoc} */
    @Override public boolean init(int txSize) {
        if (!init) {
            init = true;

            return true;
        }

        return false;
    }

    /** {@inheritDoc} */
    @Override public boolean initialized() {
        return init;
    }

    /** {@inheritDoc} */
    @Override public void addEntry(IgniteTxEntry entry) {
        assert this.entry == null : "Entry already set [cur=" + this.entry + ", new=" + entry + ']';

        this.entry = Collections.singletonList(entry);
    }

    /** {@inheritDoc} */
    @Override public void seal() {
        // No-op.
    }

    /** {@inheritDoc} */
    @Override public IgniteTxEntry singleWrite() {
        return entry != null ? entry.get(0) : null;
    }

    /** {@inheritDoc} */
    @Override public boolean mvccEnabled() {
        GridCacheContext ctx0 = cacheCtx;

        return ctx0 != null && ctx0.mvccEnabled();
    }

    /** {@inheritDoc} */
    @Override public String toString() {
        return S.toString(IgniteTxImplicitSingleStateImpl.class, this);
    }
}
