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

import java.net.InetAddress;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.cassandra.db.partitions.PartitionUpdate;
import org.apache.cassandra.net.IVerbHandler;
import org.apache.cassandra.net.MessageIn;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.serializers.MarshalException;
import org.apache.cassandra.service.StorageProxy;
import org.apache.cassandra.service.StorageService;

/**
 * Verb handler used both for hint dispatch and streaming.
 *
 * With the non-sstable format, we cannot just stream hint sstables on node decommission. So sometimes, at decommission
 * time, we might have to stream hints to a non-owning host (say, if the owning host B is down during decommission of host A).
 * In that case the handler just stores the received hint in its local hint store.
 */
public final class HintVerbHandler implements IVerbHandler<HintMessage>
{
    private static final Logger logger = LoggerFactory.getLogger(HintVerbHandler.class);

    public void doVerb(MessageIn<HintMessage> message, int id)
    {
        UUID hostId = message.payload.hostId;
        Hint hint = message.payload.hint;

        // If we see an unknown table id, it means the table, or one of the tables in the mutation, had been dropped.
        // In that case there is nothing we can really do, or should do, other than log it go on.
        // This will *not* happen due to a not-yet-seen table, because we don't transfer hints unless there
        // is schema agreement between the sender and the receiver.
        if (hint == null)
        {
            logger.trace("Failed to decode and apply a hint for {} - table with id {} is unknown",
                         hostId,
                         message.payload.unknownTableID);
            reply(id, message.from);
            return;
        }

        // We must perform validation before applying the hint, and there is no other place to do it other than here.
        try
        {
            hint.mutation.getPartitionUpdates().forEach(PartitionUpdate::validate);
        }
        catch (MarshalException e)
        {
            logger.warn("Failed to validate a hint for {} - skipped", hostId);
            reply(id, message.from);
            return;
        }

        if (!hostId.equals(StorageService.instance.getLocalHostUUID()))
        {
            // the node is not the final destination of the hint (must have gotten it from a decommissioning node),
            // so just store it locally, to be delivered later.
            HintsService.instance.write(hostId, hint);
        }
        else if (!StorageProxy.instance.appliesLocally(hint.mutation))
        {
            // the topology has changed, and we are no longer a replica of the mutation - since we don't know which node(s)
            // it has been handed over to, re-address the hint to all replicas; see CASSANDRA-5902.
            HintsService.instance.writeForAllReplicas(hint);
        }
        else
        {
            // the common path - the node is both the destination and a valid replica for the hint.
            hint.apply();
        }

        reply(id, message.from);
    }

    private static void reply(int id, InetAddress to)
    {
        MessagingService.instance().sendReply(HintResponse.message, id, to);
    }
}
