/*
 * 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.InetAddress;
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<InetAddress, 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(InetAddress endpoint)
    {
        if (endpoint.equals(FBUtilities.getBroadcastAddress()))
            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(InetAddress endpoint)
    {
        if (endpoint.equals(FBUtilities.getBroadcastAddress()))
            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;
    }
}
