/*
* Copyright 2018- Cisco
*
* 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 ves;

import evel_javalibrary.att.com.*;
import evel_javalibrary.att.com.AgentMain.EVEL_ERR_CODES;
import evel_javalibrary.att.com.EvelFault.EVEL_SEVERITIES;
import evel_javalibrary.att.com.EvelFault.EVEL_SOURCE_TYPES;
import evel_javalibrary.att.com.EvelFault.EVEL_VF_STATUSES;
import evel_javalibrary.att.com.EvelHeader.PRIORITIES;
import evel_javalibrary.att.com.EvelMobileFlow.MOBILE_GTP_PER_FLOW_METRICS;
import evel_javalibrary.att.com.EvelScalingMeasurement.MEASUREMENT_CPU_USE;
import evel_javalibrary.att.com.EvelScalingMeasurement.MEASUREMENT_VNIC_PERFORMANCE;
import evel_javalibrary.att.com.EvelStateChange.EVEL_ENTITY_STATE;
import evel_javalibrary.att.com.EvelThresholdCross.EVEL_ALERT_TYPE;
import evel_javalibrary.att.com.EvelThresholdCross.EVEL_EVENT_ACTION;
import java.net.HttpURLConnection;

import org.apache.log4j.Level;
import config.Config;

import mapper.VesVolthaMapper;
import mapper.VesVolthaAlarm;
import mapper.VesVolthaKpi;
import kafka.KafkaConsumerType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonSyntaxException;

public class VesAgent {

    private static final Logger logger = LoggerFactory.getLogger("VesAgent");

    private static VesVolthaMapper mapper;

    public static void initVes() {
        logger.info("Initializing VES Agent");
        try {
            mapper = new VesVolthaMapper();
            AgentMain.evel_initialize("http://"+Config.getVesAddress(),
                Integer.parseInt(Config.getVesPort()),
                //"/vendor_event_listener","/example_vnf",
                null,null,
                "will",
                "pill",
                null, null, null,
                //"/home/gokul/newwk/demo/vnfs/VES5.0/evel/sslcerts2/my-keystore.jks", "changeit", "changeit",
                Level.TRACE);
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }

    public static boolean sendToVES(KafkaConsumerType type, String json) throws JsonSyntaxException {
        int code = 0;

        switch (type) {
            case ALARMS:
                code = sendFault(json);
                break;
            case KPIS:
                code = sendKpi(json);
                break;
        }

        if(code == 0 || code >= HttpURLConnection.HTTP_BAD_REQUEST ) {
            return false;
        } else {
            return true;
        }
    }

    private static int sendFault(String json) {
        VesVolthaAlarm message = mapper.parseAlarm(json);

        String id = message.getId();
        String[] idsplit = id.split("\\.");
        String eventType = idsplit[idsplit.length-1];
        String ldeviceId = message.getLogicalDeviceId();
        String ts = message.getRaisedTS();
        String description = message.getDescription();
        //Type in Voltha needs to be category in VES
        String category = message.getType();
        //Category in VOLTHA needs to be type in VES
        String type = message.getCategory();
        String severity = message.getSeverity();
        String state = message.getState();
        String resourceId = message.getResourceId();

        EVEL_SEVERITIES vesSeverity = mapSeverity(severity);
        EVEL_SOURCE_TYPES vesType = getSourceType();
        EvelFault flt  = new EvelFault(
            "Fault_VOLTHA_" + eventType,
            ldeviceId + ":" + ts,
            id,
            description,
            EvelHeader.PRIORITIES.EVEL_PRIORITY_HIGH,
            vesSeverity,
            vesType,
            EVEL_VF_STATUSES.EVEL_VF_STATUS_ACTIVE);
        flt.evel_fault_addl_info_add("voltha", json);
        flt.evel_fault_addl_info_add("state", state);
        flt.evel_fault_addl_info_add("co_id", Config.getCoId());
        flt.evel_fault_addl_info_add("pod_id", Config.getPodId());
        flt.evel_fault_addl_info_add("type", type);
        flt.evel_fault_addl_info_add("resourceId", resourceId);
        flt.evel_fault_category_set(category);

        logger.info("Sending fault event");
        int code = AgentMain.evel_post_event_immediate(flt);
        logger.info("Fault event http code received: " + code);
        return code;
    }

    private static int sendKpi(String json) {
        VesVolthaKpi message = mapper.parseKpi(json);

        EvelOther ev = new EvelOther("measurement_VOLTHA_KPI", "vmname_ip");
        ev.evel_other_field_add("co_id", Config.getCoId());
        ev.evel_other_field_add("pod_id", Config.getPodId());
        ev.evel_other_field_add("type", message.getType());
        ev.evel_other_field_add("ts", message.getTs());
        ev.evel_other_field_add("slices", message.getSliceData());

        ev.evel_other_field_add("voltha", json);

        logger.info("Sending fault event");
        int code = AgentMain.evel_post_event_immediate(ev);
        logger.info("Fault event http code received: " + code);
        return code;
    }

    private static EVEL_SEVERITIES mapSeverity(String severity) {
        String severityUpper = severity.toUpperCase();
        switch (severityUpper) {
            case "INDETERMINATE":
                return EVEL_SEVERITIES.EVEL_SEVERITY_NORMAL;
            default:
                return EVEL_SEVERITIES.valueOf("EVEL_SEVERITY_" + severityUpper);
        }
    }

    private static EVEL_SOURCE_TYPES getSourceType() {
        return EVEL_SOURCE_TYPES.valueOf("EVEL_SOURCE_OLT");
    }
}
