/*
 * 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.brooklyn.entity.nosql.cassandra.customsnitch;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Properties;

import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.gms.ApplicationState;
import org.apache.cassandra.gms.EndpointState;
import org.apache.cassandra.gms.Gossiper;
import org.apache.cassandra.gms.IEndpointStateChangeSubscriber;
import org.apache.cassandra.gms.VersionedValue;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.locator.AbstractNetworkTopologySnitch;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.ResourceWatcher;
import org.apache.cassandra.utils.WrappedRunnable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A snitch that can be configured to work across clouds. It uses and
 * extends the cassandra-rackdc.properties (which is used by the 
 * GossipingPropertyFileSnitch) to add a publicip and privateip 
 * configuration.
 * <p>
 * The code is very similar to Ec2MultiRegionSnitch, except that it uses
 * the the config file rather than querying EC2 to get the IPs.
 * <p>
 * If two nodes are in the same datacenter, they will attempt to communicate
 * using the privateip. If they are in different datacenters, they will use
 * the publicip.
 */
public class MultiCloudSnitch extends AbstractNetworkTopologySnitch implements IEndpointStateChangeSubscriber
{
    // FIXME Need to submit a pull request to Cassandra (1.2.x branch) for this snitch.
    // Or could enhance GossipingPropertyFileSnitch instead, and submit PR for that.
    
    protected static final Logger logger = LoggerFactory.getLogger(MultiCloudSnitch.class);
    
    public static final String SNITCH_PROPERTIES_FILENAME = "cassandra-rackdc.properties";

    private static final String DEFAULT_DC = "UNKNOWN-DC";
    private static final String DEFAULT_RACK = "UNKNOWN-RACK";
    
    protected String rack;
    protected String datacenter;
    protected InetAddress public_ip;
    protected String private_ip;

    private volatile boolean gossipStarted;

    public MultiCloudSnitch() throws ConfigurationException
    {
        reloadConfiguration();
        logger.info("CustomSnitch using datacenter: " + datacenter + ", rack: " + rack + ", publicip: " + public_ip + ", privateip: " + private_ip);

        try
        {
            FBUtilities.resourceToFile(SNITCH_PROPERTIES_FILENAME);
            Runnable runnable = new WrappedRunnable()
            {
                protected void runMayThrow() throws ConfigurationException
                {
                    reloadConfiguration();
                }
            };
            ResourceWatcher.watch(SNITCH_PROPERTIES_FILENAME, runnable, 60 * 1000);
        }
        catch (ConfigurationException ex)
        {
            logger.debug(SNITCH_PROPERTIES_FILENAME + " found, but does not look like a plain file. Will not watch it for changes");
        }
    }

    public void reloadConfiguration() throws ConfigurationException
    {
        HashMap<InetAddress, String[]> reloadedMap = new HashMap<InetAddress, String[]>();
        String DC_PROPERTY = "dc";
        String RACK_PROPERTY = "rack";
        String PUBLIC_IP_PROPERTY = "publicip";
        String PRIVATE_IP_PROPERTY = "privateip";

        Properties properties = new Properties();
        InputStream stream = null;
        try
        {
            stream = getClass().getClassLoader().getResourceAsStream(SNITCH_PROPERTIES_FILENAME);
            properties.load(stream);
        }
        catch (Exception e)
        {
            throw new ConfigurationException("Unable to read " + SNITCH_PROPERTIES_FILENAME, e);
        }
        finally
        {
            FileUtils.closeQuietly(stream);
        }

        datacenter = properties.getProperty(DC_PROPERTY);
        rack = properties.getProperty(RACK_PROPERTY);
        private_ip = checkNotNull(properties.getProperty(PRIVATE_IP_PROPERTY), "%s in %s", PRIVATE_IP_PROPERTY, SNITCH_PROPERTIES_FILENAME);
        String public_ip_str = checkNotNull(properties.getProperty(PUBLIC_IP_PROPERTY), "%s in %s", PUBLIC_IP_PROPERTY, SNITCH_PROPERTIES_FILENAME);
        try {
            public_ip = InetAddress.getByName(public_ip_str);
        }
        catch (UnknownHostException e)
        {
            throw new ConfigurationException("Unknown host " + public_ip_str, e);
        }
        
        logger.debug("CustomSnitch reloaded, using datacenter: " + datacenter + ", rack: " + rack + ", publicip: " + public_ip + ", privateip: " + private_ip);

        if (StorageService.instance != null) // null check tolerates circular dependency; see CASSANDRA-4145
            StorageService.instance.getTokenMetadata().invalidateCaches();

        if (gossipStarted)
            StorageService.instance.gossipSnitchInfo();
    }


    public String getRack(InetAddress endpoint)
    {
        if (endpoint.equals(FBUtilities.getBroadcastAddress()))
            return rack;
        EndpointState state = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
        if (state == null || state.getApplicationState(ApplicationState.RACK) == null)
            return DEFAULT_RACK;
        return state.getApplicationState(ApplicationState.RACK).value;
    }

    public String getDatacenter(InetAddress endpoint)
    {
        if (endpoint.equals(FBUtilities.getBroadcastAddress()))
            return datacenter;
        EndpointState state = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
        if (state == null || state.getApplicationState(ApplicationState.DC) == null)
            return DEFAULT_DC;
        return state.getApplicationState(ApplicationState.DC).value;
    }
    
    public void onJoin(InetAddress endpoint, EndpointState epState)
    {
        if (epState.getApplicationState(ApplicationState.INTERNAL_IP) != null)
            reConnect(endpoint, epState.getApplicationState(ApplicationState.INTERNAL_IP));
    }

    public void onChange(InetAddress endpoint, ApplicationState state, VersionedValue value)
    {
        if (state == ApplicationState.INTERNAL_IP)
            reConnect(endpoint, value);
    }

    public void onAlive(InetAddress endpoint, EndpointState state)
    {
        if (state.getApplicationState(ApplicationState.INTERNAL_IP) != null)
            reConnect(endpoint, state.getApplicationState(ApplicationState.INTERNAL_IP));
    }

    public void onDead(InetAddress endpoint, EndpointState state)
    {
        // do nothing
    }

    public void onRestart(InetAddress endpoint, EndpointState state)
    {
        // do nothing
    }

    public void onRemove(InetAddress endpoint)
    {
        // do nothing.
    }

    private void reConnect(InetAddress endpoint, VersionedValue versionedValue)
    {
        if (!getDatacenter(endpoint).equals(getDatacenter(public_ip)))
            return; // do nothing return back...

        try
        {
            InetAddress remoteIP = InetAddress.getByName(versionedValue.value);
            MessagingService.instance().getConnectionPool(endpoint).reset(remoteIP);
            logger.debug(String.format("Intiated reconnect to an Internal IP %s for the %s", remoteIP, endpoint));
        } catch (UnknownHostException e)
        {
            logger.error("Error in getting the IP address resolved: ", e);
        }
    }

    @Override
    public void gossiperStarting()
    {
        super.gossiperStarting();
        Gossiper.instance.addLocalApplicationState(ApplicationState.INTERNAL_IP, StorageService.instance.valueFactory.internalIP(private_ip));
        Gossiper.instance.register(this);
    }
}
