/*
 * 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;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.concurrent.atomic.AtomicInteger;
import javax.cache.processor.MutableEntry;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheEntryProcessor;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.binary.BinaryMarshaller;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;

/**
 * Test for value copy in entry processor.
 */
public class CacheEntryProcessorCopySelfTest extends GridCommonAbstractTest {
    /** Old value. */
    private static final int OLD_VAL = 100;

    /** New value. */
    private static final int NEW_VAL = 200;

    /** Empty array. */
    private static final int[] EMPTY_ARR = new int[0];

    /** Deserializations counter. */
    private static final AtomicInteger cnt = new AtomicInteger();

    /** p2p enabled. */
    private boolean p2pEnabled;

    /** {@inheritDoc} */
    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);

        cfg.setIncludeEventTypes(EMPTY_ARR);

        cfg.setPeerClassLoadingEnabled(p2pEnabled);

        return cfg;
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testMutableEntryWithP2PEnabled() throws Exception {
        doTestMutableEntry(true);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testMutableEntryWithP2PDisabled() throws Exception {
        doTestMutableEntry(false);
    }

    /**
     *
     */
    private void doTestMutableEntry(boolean p2pEnabled) throws Exception {
        this.p2pEnabled = p2pEnabled;

        Ignite grid = startGrid();

        assertEquals(p2pEnabled, grid.configuration().isPeerClassLoadingEnabled());

        try {
            // One deserialization due to copyOnRead == true.
            doTest(true, false, OLD_VAL, 1);

            // One deserialization due to copyOnRead == true.
            // Additional deserialization in case p2p enabled and not BinaryMarshaller due to storeValue == true on update entry.
            doTest(true, true, NEW_VAL, p2pEnabled &&
                !(grid.configuration().getMarshaller() instanceof BinaryMarshaller) ? 2 : 1);

            // No deserialization.
            doTest(false, false, NEW_VAL, 0);

            // One deserialization due to storeValue == true.
            doTest(false, true, NEW_VAL, 1);
        }
        finally {
            stopAllGrids();
        }
    }

    /**
     * @param cpOnRead Copy on read.
     * @param mutate Mutate.
     * @param expVal Expected value.
     * @param expCnt Expected deserializations count.
     */
    @SuppressWarnings("unchecked")
    private void doTest(boolean cpOnRead, final boolean mutate, int expVal, int expCnt) throws Exception {

        Ignite ignite = grid();

        CacheConfiguration ccfg = defaultCacheConfiguration();
        ccfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
        ccfg.setCopyOnRead(cpOnRead);
        ccfg.setNearConfiguration(null);

        IgniteCache<Integer, Value> cache = null;

        try {
            cache = ignite.createCache(ccfg);

            cache.put(0, new Value(OLD_VAL));

            cache.get(0);

            cnt.set(0);

            cache.invoke(0, new CacheEntryProcessor<Integer, Value, Object>() {
                @Override public Object process(MutableEntry<Integer, Value> entry, Object... args) {
                    Value val = entry.getValue();

                    val.i = NEW_VAL;

                    if (mutate)
                        entry.setValue(val);

                    return null;
                }
            });

            GridCacheAdapter ca = (GridCacheAdapter)((IgniteCacheProxy)cache).internalProxy().delegate();

            GridCacheEntryEx entry = ca.entryEx(0);

            entry.unswap();

            CacheObject obj = entry.peekVisibleValue();

            entry.touch();

            int actCnt = cnt.get();

            if (obj instanceof BinaryObject)
                if (cpOnRead)
                    assertEquals(expVal, (int)((BinaryObject)obj).field("i"));
                else
                    assertEquals(expVal, ((Value)U.field(obj, "obj")).i);
            else {
                if (storeValue(cache))
                    assertEquals(expVal, U.<Value>field(obj, "val").i);
                else
                    assertEquals(expVal, CU.<Value>value(obj, ((IgniteCacheProxy)cache).context(), false).i);
            }

            assertEquals(expCnt, actCnt);
        }
        finally {
            if (cache != null)
                cache.destroy();
        }
    }

    /**
     * @param cache Cache.
     */
    private static boolean storeValue(IgniteCache cache) {
        return ((IgniteCacheProxy)cache).context().cacheObjectContext().storeValue();
    }

    /**
     *
     */
    private static class Value implements Externalizable {
        /**  */
        private int i;

        /**
         * Default constructor (required by Externalizable).
         */
        public Value() {
        }

        /**
         * @param i I.
         */
        public Value(int i) {
            this.i = i;
        }

        /** {@inheritDoc} */
        @Override public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(i);
        }

        /** {@inheritDoc} */
        @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            i = in.readInt();

            cnt.incrementAndGet();
        }
    }
}
