/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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.xran.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.config.Config;
import org.onosproject.xran.codecs.api.ECGI;
import org.onosproject.xran.codecs.api.EUTRANCellIdentifier;
import org.onosproject.xran.codecs.api.PLMNIdentity;
import org.onosproject.xran.codecs.util.HexConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Xran config.
 */
public class XranConfig extends Config<ApplicationId> {

    private static final String CELLS = "active_cells";

    private static final String PLMN_ID = "plmn_id";

    private static final String ECI_ID = "eci";

    private static final String IP_ADDR = "ip_addr";

    private static final String XRANC_PORT = "xranc_port";

    private static final String XRANC_CELLCONFIG_INTERVAL = "xranc_cellconfigrequest_interval_seconds";

    private static final String RX_SIGNAL_MEAS_REPORT_INTERVAL = "rx_signal_meas_report_interval_ms";

    private static final String L2_MEAS_REPORT_INTERVAL = "l2_meas_report_interval_ms";

    private static final String ADMISSION_SUCCESS = "admission_success";

    private static final String BEARER_SUCCESS = "bearer_success";

    private static final String NO_MEAS_LINK_REMOVAL = "no_meas_link_removal_ms";

    private static final String IDLE_UE_REMOVAL = "idle_ue_removal_ms";

    private static final String NORTHBOUND_TIMEOUT = "nb_response_timeout_ms";

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

    /**
     * Get a list of all CELLs inside the configuration file.
     *
     * @return Map of CELL IP to ECGI
     */
    public Map<IpAddress, ECGI> activeCellSet() {
        Map<IpAddress, ECGI> cells = new ConcurrentHashMap<>();

        JsonNode cellsNode = object.get(CELLS);
        if (cellsNode == null) {
            log.warn("no cells have been provided!");
            return cells;
        }

        cellsNode.forEach(cellNode -> {
            String plmnId = cellNode.get(PLMN_ID).asText();
            String eci = cellNode.get(ECI_ID).asText();

            String ipAddress = cellNode.get(IP_ADDR).asText();

            ECGI ecgi = hexToEcgi(plmnId, eci);
            cells.put(IpAddress.valueOf(ipAddress), ecgi);
        });

        return cells;
    }

    /**
     * Get flag for ADMISSION_SUCCESS field in configuration.
     *
     * @return boolean value in configuration
     */
    public boolean admissionFlag() {
        JsonNode flag = object.get(ADMISSION_SUCCESS);
        return flag != null && flag.asBoolean();
    }

    /**
     * Get flag for BEARER_SUCCESS field in configuration.
     *
     * @return boolean value in configuration
     */
    public boolean bearerFlag() {
        JsonNode flag = object.get(BEARER_SUCCESS);
        return flag != null && flag.asBoolean();
    }

    /**
     * Get port for xRAN controller server to bind to from configuration.
     *
     * @return port number
     */
    public int getXrancPort() {
        return object.get(XRANC_PORT).asInt();
    }

    /**
     * Get config request interval from configuration.
     *
     * @return interval in seconds
     */
    public int getConfigRequestInterval() {
        return object.get(XRANC_CELLCONFIG_INTERVAL).asInt();
    }

    /**
     * Get rx signal interval from configuration.
     *
     * @return interval in milliseconds
     */
    public int getRxSignalInterval() {
        return object.get(RX_SIGNAL_MEAS_REPORT_INTERVAL).asInt();
    }

    /**
     * Get l2 measurement interval from configuration.
     *
     * @return interval in milliseconds
     */
    public int getL2MeasInterval() {
        return object.get(L2_MEAS_REPORT_INTERVAL).asInt();
    }

    /**
     * Get removal time of link after not getting measurement from configuration.
     *
     * @return interval in milliseconds
     */
    public int getNoMeasLinkRemoval() {
        return object.get(NO_MEAS_LINK_REMOVAL).asInt();
    }

    /**
     * Get removal time of UE after being IDLE from configuration.
     *
     * @return interval in milliseconds
     */
    public int getIdleUeRemoval() {
        return object.get(IDLE_UE_REMOVAL).asInt();
    }

    /**
     * Get northbound timeout when waiting for responses from configuration.
     *
     * @return interval in milliseconds
     */
    public int getNorthBoundTimeout() {
        return object.get(NORTHBOUND_TIMEOUT).asInt();
    }

    /**
     * Get ECGI from HEX representation of PLMN_ID and ECI.
     *
     * @param plmnId  HEX string of PLMN_ID
     * @param eci     HEX string of ECI
     * @return new ECGI object
     */
    private ECGI hexToEcgi(String plmnId, String eci) {
        byte[] bytes = HexConverter.fromShortHexString(plmnId);
        byte[] bytearray = DatatypeConverter.parseHexBinary(eci);

        InputStream inputStream = new ByteArrayInputStream(bytearray);

        PLMNIdentity plmnIdentity = new PLMNIdentity(bytes);
        EUTRANCellIdentifier eutranCellIdentifier = new EUTRANCellIdentifier(bytearray, 28);

        ECGI ecgi = new ECGI();
        ecgi.setEUTRANcellIdentifier(eutranCellIdentifier);
        ecgi.setPLMNIdentity(plmnIdentity);
        try {
            ecgi.decode(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return ecgi;
    }
}
