/*
 * 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.Ignore;
import org.junit.Test;

/**
 * Test for value copy in entry processor.
 */
// Test fails due to incorrect handling of CacheConfiguration#getCopyOnRead() and
// CacheObjectContext#storeValue() properties. Heap storage should be redesigned in this ticket.
@Ignore("https://issues.apache.org/jira/browse/IGNITE-10420")
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();
        }
    }
}
