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

import java.util.Collection;
import java.util.Map;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.IgniteCacheProxy;
import org.apache.ignite.internal.util.lang.GridPlainCallable;
import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.plugin.security.SecurityPermission;
import org.apache.ignite.stream.StreamReceiver;
import org.jetbrains.annotations.Nullable;

/**
 * Job to put entries to cache on affinity node.
 */
class DataStreamerUpdateJob implements GridPlainCallable<Object> {
    /** */
    private final GridKernalContext ctx;

    /** */
    private final IgniteLogger log;

    /** Cache name. */
    private final String cacheName;

    /** Entries to put. */
    private final Collection<DataStreamerEntry> col;

    /** {@code True} to ignore deployment ownership. */
    private final boolean ignoreDepOwnership;

    /** */
    private final boolean skipStore;

    /** */
    private final StreamReceiver rcvr;

    /** */
    private boolean keepBinary;

    /**
     * @param ctx Context.
     * @param log Log.
     * @param cacheName Cache name.
     * @param col Entries to put.
     * @param ignoreDepOwnership {@code True} to ignore deployment ownership.
     * @param skipStore Skip store flag.
     * @param rcvr Updater.
     */
    DataStreamerUpdateJob(
        GridKernalContext ctx,
        IgniteLogger log,
        @Nullable String cacheName,
        Collection<DataStreamerEntry> col,
        boolean ignoreDepOwnership,
        boolean skipStore,
        boolean keepBinary,
        StreamReceiver<?, ?> rcvr) {
        this.ctx = ctx;
        this.log = log;

        assert col != null && !col.isEmpty();
        assert rcvr != null;

        this.cacheName = cacheName;
        this.col = col;
        this.ignoreDepOwnership = ignoreDepOwnership;
        this.skipStore = skipStore;
        this.keepBinary = keepBinary;
        this.rcvr = rcvr;
    }

    /** {@inheritDoc} */
    @SuppressWarnings("unchecked")
    @Override public Object call() throws Exception {
        if (log.isDebugEnabled())
            log.debug("Running put job [nodeId=" + ctx.localNodeId() + ", size=" + col.size() + ']');

        IgniteCacheProxy cache = ctx.cache().jcache(cacheName).cacheNoGate();

        cache.context().awaitStarted();

        if (skipStore)
            cache = (IgniteCacheProxy<?, ?>)cache.withSkipStore();

        if (keepBinary)
            cache = (IgniteCacheProxy<?, ?>)cache.withKeepBinary();

        if (ignoreDepOwnership)
            cache.context().deploy().ignoreOwnership(true);

        try {
            final GridCacheContext cctx = cache.context();

            for (DataStreamerEntry e : col) {
                e.getKey().finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader());

                CacheObject val = e.getValue();

                if (val != null) {
                    checkSecurityPermission(SecurityPermission.CACHE_PUT);

                    val.finishUnmarshal(cctx.cacheObjectContext(), cctx.deploy().globalLoader());
                }
                else
                    checkSecurityPermission(SecurityPermission.CACHE_REMOVE);
            }

            if (unwrapEntries()) {
                Collection<Map.Entry> col0 = F.viewReadOnly(col, new C1<DataStreamerEntry, Map.Entry>() {
                    @Override public Map.Entry apply(DataStreamerEntry e) {
                        return e.toEntry(cctx, keepBinary);
                    }
                });

                rcvr.receive(cache, col0);
            }
            else
                rcvr.receive(cache, col);

            return null;
        }
        finally {
            if (ignoreDepOwnership)
                cache.context().deploy().ignoreOwnership(false);

            if (log.isDebugEnabled())
                log.debug("Update job finished on node: " + ctx.localNodeId());
        }
    }

    /**
     * @return {@code True} if need to unwrap internal entries.
     */
    private boolean unwrapEntries() {
        return !(rcvr instanceof DataStreamerCacheUpdaters.InternalUpdater);
    }

    /**
     * @param perm Security permission.
     * @throws org.apache.ignite.plugin.security.SecurityException If permission is not enough.
     */
    private void checkSecurityPermission(SecurityPermission perm)
        throws org.apache.ignite.plugin.security.SecurityException {
        if (!ctx.security().enabled())
            return;

        ctx.security().authorize(cacheName, perm, null);
    }
}
