/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed 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.onosproject.virtualbng;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implementation of ConfigurationService which reads virtual BNG
 * configuration from a file.
 */
@Component(immediate = true)
@Service
public class VbngConfigurationManager implements VbngConfigurationService {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private static final String CONFIG_DIR = "../config";
    private static final String DEFAULT_CONFIG_FILE = "virtualbng.json";
    private String configFileName = DEFAULT_CONFIG_FILE;

    // If all the IP addresses of one IP prefix are assigned, then we
    // mark the value of this IP prefix as false, otherwise as true.
    private Map<IpPrefix, Boolean> localPublicIpPrefixes =
            new ConcurrentHashMap<>();

    // Map from private IP address to public IP address
    private Map<IpAddress, IpAddress> ipAddressMap =
            new ConcurrentHashMap<>();

    private IpAddress nextHopIpAddress;
    private MacAddress macOfPublicIpAddresses;

    @Activate
    public void activate() {
        readConfiguration();
        log.info("vBNG configuration service started");
    }

    @Deactivate
    public void deactivate() {
        log.info("vBNG configuration service stopped");
    }

    /**
     * Instructs the configuration reader to read the configuration from the
     * file.
     */
    public void readConfiguration() {
        readConfiguration(configFileName);
    }

    /**
     * Reads virtual BNG information contained in configuration file.
     *
     * @param configFilename the name of the configuration file for the virtual
     * BNG application
     */
    private void readConfiguration(String configFilename) {
        File configFile = new File(CONFIG_DIR, configFilename);
        ObjectMapper mapper = new ObjectMapper();

        try {
            log.info("Loading config: {}", configFile.getAbsolutePath());
            VbngConfiguration config = mapper.readValue(configFile,
                                                    VbngConfiguration.class);
            for (IpPrefix prefix : config.getLocalPublicIpPrefixes()) {
                localPublicIpPrefixes.put(prefix, true);
            }
            nextHopIpAddress = config.getNextHopIpAddress();
            macOfPublicIpAddresses = config.getPublicFacingMac();

        } catch (FileNotFoundException e) {
            log.warn("Configuration file not found: {}", configFileName);
        } catch (IOException e) {
            log.error("Error loading configuration", e);
        }
    }

    @Override
    public IpAddress getNextHopIpAddress() {
        return nextHopIpAddress;
    }

    @Override
    public MacAddress getPublicFacingMac() {
        return macOfPublicIpAddresses;
    }

    // TODO handle the case: the number of public IP addresses is not enough
    // for 1:1 mapping from public IP to private IP.
    @Override
    public synchronized IpAddress getAvailablePublicIpAddress(IpAddress
                                                           privateIpAddress) {
        // If there is already a mapping entry for the private IP address,
        // then fetch the public IP address in the mapping entry and return it.
        IpAddress publicIpAddress = ipAddressMap.get(privateIpAddress);
        if (publicIpAddress != null) {
            return publicIpAddress;
        }
        // There is no mapping for the private IP address.
        Iterator<Entry<IpPrefix, Boolean>> prefixes =
                localPublicIpPrefixes.entrySet().iterator();
        while (prefixes.hasNext()) {
            Entry<IpPrefix, Boolean> prefix = prefixes.next();
            if (!prefix.getValue()) {
                continue;
            }

            if (prefix.getKey().prefixLength() == 32) {
                updateIpPrefixStatus(prefix.getKey(), false);
                publicIpAddress = prefix.getKey().address();
                ipAddressMap.put(privateIpAddress, publicIpAddress);
                return publicIpAddress;
            }

            int prefixLen = prefix.getKey().prefixLength();
            int availableIpNum = (int) Math.pow(2,
                    IpPrefix.MAX_INET_MASK_LENGTH - prefixLen) - 1;
            for (int i = 1; i <= availableIpNum; i++) {
                publicIpAddress =
                        increaseIpAddress(prefix.getKey().address(), i);
                if (publicIpAddress == null) {
                    return null;
                }
                if (ipAddressMap.values().contains(publicIpAddress)) {
                    continue;
                } else if (i == availableIpNum) {
                    // All the IP addresses are assigned out
                    // Update this IP prefix status to false
                    // Note: in this version we do not consider the
                    // IP recycling issue.
                    updateIpPrefixStatus(prefix.getKey(), false);
                    ipAddressMap.put(privateIpAddress, publicIpAddress);
                    return publicIpAddress;
                } else {
                    ipAddressMap.put(privateIpAddress, publicIpAddress);
                    return publicIpAddress;
                }
            }
        }
        return null;
    }

    @Override
    public IpAddress getAssignedPublicIpAddress(IpAddress privateIpAddress) {
        return ipAddressMap.get(privateIpAddress);
    }

    @Override
    public boolean isAssignedPublicIpAddress(IpAddress ipAddress) {
        return ipAddressMap.containsValue(ipAddress);
    }

    @Override
    public synchronized IpAddress recycleAssignedPublicIpAddress(IpAddress
                                                    privateIpAddress) {
        IpAddress publicIpAddress = ipAddressMap.remove(privateIpAddress);
        if (publicIpAddress == null) {
            return null;
        }

        Iterator<Entry<IpPrefix, Boolean>> prefixes =
                localPublicIpPrefixes.entrySet().iterator();
        while (prefixes.hasNext()) {
            Entry<IpPrefix, Boolean> prefixEntry = prefixes.next();
            if (prefixEntry.getKey().contains(publicIpAddress)
                    && !prefixEntry.getValue()) {
                updateIpPrefixStatus(prefixEntry.getKey(), true);
            }
        }
        log.info("[DELETE] Private IP to Public IP mapping: {} --> {}",
                 privateIpAddress, publicIpAddress);
        return publicIpAddress;
    }

    @Override
    public Map<IpAddress, IpAddress> getIpAddressMappings() {
        return Collections.unmodifiableMap(ipAddressMap);
    }

    @Override
    public synchronized boolean assignSpecifiedPublicIp(IpAddress publicIpAddress,
                                  IpAddress privateIpAddress) {

        // Judge whether this public IP address is in our public IP
        // prefix/address list.
        boolean isPublicIpExist = false;
        for (Entry<IpPrefix, Boolean> prefix: localPublicIpPrefixes.entrySet()) {
            if (prefix.getKey().contains(publicIpAddress)) {
                isPublicIpExist = true;

                // Judge whether this public IP address is already assigned
                if (!prefix.getValue() ||
                        isAssignedPublicIpAddress(publicIpAddress)) {
                    log.info("The public IP address {} is already assigned, "
                            + "and not available.", publicIpAddress);
                    return false;
                }

                // The public IP address is still available
                // Store the mapping from private IP address to public IP address
                ipAddressMap.put(privateIpAddress, publicIpAddress);

                // Update the prefix status
                if (prefix.getKey().prefixLength() == 32) {
                    updateIpPrefixStatus(prefix.getKey(), false);
                    return true;
                }

                // Judge whether the prefix of this public IP address is used
                // up, if so, update the IP prefix status.
                int prefixLen = prefix.getKey().prefixLength();
                int availableIpNum = (int) Math.pow(2,
                        IpPrefix.MAX_INET_MASK_LENGTH - prefixLen) - 1;
                int usedIpNum = 0;
                for (Entry<IpAddress, IpAddress> ipAddressMapEntry:
                    ipAddressMap.entrySet()) {
                    if (prefix.getKey().contains(ipAddressMapEntry.getValue())) {
                        usedIpNum = usedIpNum + 1;
                    }
                }
                if (usedIpNum == availableIpNum) {
                    updateIpPrefixStatus(prefix.getKey(), false);
                }

                return true;
            }
        }
        if (!isPublicIpExist) {
            log.info("The public IP address {} retrieved from XOS mapping does "
                    + "not exist", publicIpAddress);
        }
        return false;
    }

    /**
     * Generates a new IP address base on a given IP address plus a number to
     * increase.
     *
     * @param ipAddress the IP address to increase
     * @param num the number for ipAddress to add
     * @return the new IP address after increase
     */
    private IpAddress increaseIpAddress(IpAddress ipAddress, int num) {
        if (ipAddress.isIp6()) {
            log.info("vBNG currently does not handle IPv6");
            return null;
        }
        return IpAddress.valueOf(ipAddress.getIp4Address().toInt() + num);
    }

    /**
     * Updates the IP prefix status in the local public IP prefix table.
     *
     * @param ipPprefix the IP prefix to update
     * @param b the new value for the IP prefix
     */
    private void updateIpPrefixStatus(IpPrefix ipPprefix, boolean b) {
            localPublicIpPrefixes.replace(ipPprefix, b);
    }

}
