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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;

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

import org.apache.cassandra.dht.Range;
import org.apache.cassandra.dht.Token;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.schema.SchemaConstants;
import org.apache.cassandra.service.ClientWarn;
import org.apache.cassandra.service.StorageService;


/**
 * This class returns the nodes responsible for a given
 * key but does not respect rack awareness. Basically
 * returns the RF nodes that lie right next to each other
 * on the ring.
 */
public class SimpleStrategy extends AbstractReplicationStrategy
{
    private static final String REPLICATION_FACTOR = "replication_factor";
    private static final Logger logger = LoggerFactory.getLogger(SimpleStrategy.class);
    private final ReplicationFactor rf;

    public SimpleStrategy(String keyspaceName, TokenMetadata tokenMetadata, IEndpointSnitch snitch, Map<String, String> configOptions)
    {
        super(keyspaceName, tokenMetadata, snitch, configOptions);
        validateOptionsInternal(configOptions);
        this.rf = ReplicationFactor.fromString(this.configOptions.get(REPLICATION_FACTOR));
    }

    @Override
    public EndpointsForRange calculateNaturalReplicas(Token token, TokenMetadata metadata)
    {
        ArrayList<Token> ring = metadata.sortedTokens();
        if (ring.isEmpty())
            return EndpointsForRange.empty(new Range<>(metadata.partitioner.getMinimumToken(), metadata.partitioner.getMinimumToken()));

        Token replicaEnd = TokenMetadata.firstToken(ring, token);
        Token replicaStart = metadata.getPredecessor(replicaEnd);
        Range<Token> replicaRange = new Range<>(replicaStart, replicaEnd);
        Iterator<Token> iter = TokenMetadata.ringIterator(ring, token, false);

        EndpointsForRange.Builder replicas = new EndpointsForRange.Builder(replicaRange, rf.allReplicas);

        // Add the token at the index by default
        while (replicas.size() < rf.allReplicas && iter.hasNext())
        {
            Token tk = iter.next();
            InetAddressAndPort ep = metadata.getEndpoint(tk);
            if (!replicas.endpoints().contains(ep))
                replicas.add(new Replica(ep, replicaRange, replicas.size() < rf.fullReplicas));
        }

        return replicas.build();
    }

    @Override
    public ReplicationFactor getReplicationFactor()
    {
        return rf;
    }

    private static void validateOptionsInternal(Map<String, String> configOptions) throws ConfigurationException
    {
        if (configOptions.get(REPLICATION_FACTOR) == null)
            throw new ConfigurationException("SimpleStrategy requires a replication_factor strategy option.");
    }

    @Override
    public void validateOptions() throws ConfigurationException
    {
        validateOptionsInternal(configOptions);
        validateReplicationFactor(configOptions.get(REPLICATION_FACTOR));
    }

    @Override
    public void maybeWarnOnOptions()
    {
        if (!SchemaConstants.isSystemKeyspace(keyspaceName))
        {
            int nodeCount = StorageService.instance.getHostIdToEndpoint().size();
            // nodeCount==0 on many tests
            if (rf.fullReplicas > nodeCount && nodeCount != 0)
            {
                String msg = "Your replication factor " + rf.fullReplicas
                             + " for keyspace "
                             + keyspaceName
                             + " is higher than the number of nodes "
                             + nodeCount;
                ClientWarn.instance.warn(msg);
                logger.warn(msg);
            }
        }
    }

    @Override
    public Collection<String> recognizedOptions()
    {
        return Collections.singleton(REPLICATION_FACTOR);
    }
}
