/*
 * 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.io.DataInputStream;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.cassandra.db.SystemKeyspace;
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.io.util.FileUtils;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.JVMStabilityInspector;

/**
 * {@code
 * A snitch that assumes a Cloudstack Zone follows the typical convention
 * <country>-<location>-<availability zone> and uses the country/location
 * tuple as a datacenter and the availability zone as a rack
 * }
 */

public class CloudstackSnitch extends AbstractNetworkTopologySnitch
{
    protected static final Logger logger = LoggerFactory.getLogger(CloudstackSnitch.class);
    protected static final String ZONE_NAME_QUERY_URI = "/latest/meta-data/availability-zone";

    private Map<InetAddressAndPort, Map<String, String>> savedEndpoints;

    private static final String DEFAULT_DC = "UNKNOWN-DC";
    private static final String DEFAULT_RACK = "UNKNOWN-RACK";
    private static final String[] LEASE_FILES =
    {
        "file:///var/lib/dhcp/dhclient.eth0.leases",
        "file:///var/lib/dhclient/dhclient.eth0.leases"
    };

    protected String csZoneDc;
    protected String csZoneRack;

    public CloudstackSnitch() throws IOException, ConfigurationException
    {
        String endpoint = csMetadataEndpoint();
        String zone = csQueryMetadata(endpoint + ZONE_NAME_QUERY_URI);
        String zone_parts[] = zone.split("-");

        if (zone_parts.length != 3)
        {
            throw new ConfigurationException("CloudstackSnitch cannot handle invalid zone format: " + zone);
        }
        csZoneDc = zone_parts[0] + "-" + zone_parts[1];
        csZoneRack = zone_parts[2];
    }

    public String getRack(InetAddressAndPort endpoint)
    {
        if (endpoint.equals(FBUtilities.getBroadcastAddressAndPort()))
            return csZoneRack;
        EndpointState state = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
        if (state == null || state.getApplicationState(ApplicationState.RACK) == null)
        {
            if (savedEndpoints == null)
                savedEndpoints = SystemKeyspace.loadDcRackInfo();
            if (savedEndpoints.containsKey(endpoint))
                return savedEndpoints.get(endpoint).get("rack");
            return DEFAULT_RACK;
        }
        return state.getApplicationState(ApplicationState.RACK).value;
    }

    public String getDatacenter(InetAddressAndPort endpoint)
    {
        if (endpoint.equals(FBUtilities.getBroadcastAddressAndPort()))
            return csZoneDc;
        EndpointState state = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
        if (state == null || state.getApplicationState(ApplicationState.DC) == null)
        {
            if (savedEndpoints == null)
                savedEndpoints = SystemKeyspace.loadDcRackInfo();
            if (savedEndpoints.containsKey(endpoint))
                return savedEndpoints.get(endpoint).get("data_center");
            return DEFAULT_DC;
        }
        return state.getApplicationState(ApplicationState.DC).value;
    }

    String csQueryMetadata(String url) throws ConfigurationException, IOException
    {
        HttpURLConnection conn = null;
        DataInputStream is = null;

        try
        {
            conn = (HttpURLConnection) new URL(url).openConnection();
        }
        catch (Exception e)
        {
            throw new ConfigurationException("CloudstackSnitch cannot query wrong metadata URL: " + url);
        }
        try
        {
            conn.setRequestMethod("GET");
            if (conn.getResponseCode() != 200)
            {
                throw new ConfigurationException("CloudstackSnitch was unable to query metadata.");
            }

            int cl = conn.getContentLength();
            byte[] b = new byte[cl];
            is = new DataInputStream(new BufferedInputStream(conn.getInputStream()));
            is.readFully(b);
            return new String(b, StandardCharsets.UTF_8);
        }
        finally
        {
            FileUtils.close(is);
            conn.disconnect();
        }
    }

    String csMetadataEndpoint() throws ConfigurationException
    {
        for (String lease_uri: LEASE_FILES)
        {
            try
            {
                File lease_file = new File(new URI(lease_uri));
                if (lease_file.exists())
                {
                    return csEndpointFromLease(lease_file);
                }
            }
            catch (Exception e)
            {
                JVMStabilityInspector.inspectThrowable(e);
                continue;
            }

        }

        throw new ConfigurationException("No valid DHCP lease file could be found.");
    }

    String csEndpointFromLease(File lease) throws ConfigurationException
    {
        String line;
        String endpoint = null;
        Pattern identifierPattern = Pattern.compile("^[ \t]*option dhcp-server-identifier (.*);$");

        try (BufferedReader reader = new BufferedReader(new FileReader(lease)))
        {

            while ((line = reader.readLine()) != null)
            {
                Matcher matcher = identifierPattern.matcher(line);

                if (matcher.find())
                {
                    endpoint = matcher.group(1);
                    break;
                }
            }
        }
        catch (Exception e)
        {
            throw new ConfigurationException("CloudstackSnitch cannot access lease file.");
        }

        if (endpoint == null)
        {
            throw new ConfigurationException("No metadata server could be found in lease file.");
        }

        return "http://" + endpoint;
    }
}
