/*
 * Copyright 2016-present 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.drivers.fujitsu;

import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DeviceId;
import org.onosproject.drivers.fujitsu.behaviour.VoltPonLinkConfig;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.netconf.NetconfController;
import org.slf4j.Logger;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.ImmutableSet;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.drivers.fujitsu.FujitsuVoltXmlUtility.*;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Implementation to get and set parameters available in vOLT
 * through the Netconf protocol.
 */
public class FujitsuVoltPonLinkConfig extends AbstractHandlerBehaviour
        implements VoltPonLinkConfig {

    private final Logger log = getLogger(FujitsuVoltPonLinkConfig.class);
    private static final Map<String, List<Integer>> PON_LINK_PARAMS = new HashMap<String, List<Integer>>() {
        {
            put("onu-discovery-interval", Arrays.asList(ONU_DISCOVERY_INTERVAL_MIN, ONU_DISCOVERY_INTERVAL_MAX));
            put("dba-cycle-time", Arrays.asList(DBA_CYCLE_TIME_MIN, DBA_CYCLE_TIME_MAX));
            put("mac-age-time", Arrays.asList(MAC_AGE_TIME_MIN, MAC_AGE_TIME_MAX));
            put("lof-threshold", Arrays.asList(LOF_THRESHOLD_MIN, LOF_THRESHOLD_MAX));
            put("los-threshold", Arrays.asList(LOS_THRESHOLD_MIN, LOS_THRESHOLD_MAX));
            put(ONU_DISCOVERY_MODE, null);
            put(PM_ENABLE, null);
            put(ADMIN_STATE, null);
        }
    };
    private static final String VOLT_PORTS = "volt-ports";
    private static final String GPON_PONLINK_PORTS = "gpon-ponlink-ports";
    private static final String GPON_PONLINK_PORT = "gpon-ponlink-port";
    private static final String ADMIN_STATE = "admin-state";
    private static final String ONU_DISCOVERY_MODE = "onu-discovery-mode";
    private static final String PM_ENABLE = "pm-enable";
    private static final Set<String> ADMINSTATES =
            ImmutableSet.of("enable", "disable");
    private static final Set<String> ONUDISCOVERYMODES =
            ImmutableSet.of("auto", "manual", "disabled");
    private static final Set<String> PMENABLES =
            ImmutableSet.of("true", "false");

    private static final int ONU_DISCOVERY_INTERVAL_MIN = 1;
    private static final int ONU_DISCOVERY_INTERVAL_MAX = 3600;
    private static final int DBA_CYCLE_TIME_MIN = 2;
    private static final int DBA_CYCLE_TIME_MAX = 40;
    private static final int MAC_AGE_TIME_MIN = 1000;
    private static final int MAC_AGE_TIME_MAX = 3600000;
    private static final int LOF_THRESHOLD_MIN = 1;
    private static final int LOF_THRESHOLD_MAX = 10;
    private static final int LOS_THRESHOLD_MIN = 1;
    private static final int LOS_THRESHOLD_MAX = 10;
    private static final int RANGE_MIN = 0;
    private static final int RANGE_MAX = 1;

    @Override
    public String getPonLinks(String target) {
        DriverHandler handler = handler();
        NetconfController controller = handler.get(NetconfController.class);
        MastershipService mastershipService = handler.get(MastershipService.class);
        DeviceId ncDeviceId = handler.data().deviceId();
        checkNotNull(controller, "Netconf controller is null");
        String reply = null;

        if (!mastershipService.isLocalMaster(ncDeviceId)) {
            log.warn("Not master for {} Use {} to execute command",
                     ncDeviceId,
                     mastershipService.getMasterFor(ncDeviceId));
            return null;
        }

        try {
            StringBuilder request = new StringBuilder();
            request.append(VOLT_NE_OPEN).append(VOLT_NE_NAMESPACE);
            request.append(ANGLE_RIGHT).append(NEW_LINE);
            request.append(buildStartTag(VOLT_PORTS));
            if (target != null) {
                int pon;
                try {
                    pon = Integer.parseInt(target);
                    if (pon <= ZERO) {
                        log.error("Invalid integer for ponlink-id:{}", target);
                        return null;
                    }
                } catch (NumberFormatException e) {
                    log.error("Non-number input for ponlink-id:{}", target);
                    return null;
                }
                request.append(buildStartTag(GPON_PONLINK_PORTS));
                request.append(buildStartTag(GPON_PONLINK_PORT));
                request.append(buildStartTag(PONLINK_ID, false));
                request.append(target);
                request.append(buildEndTag(PONLINK_ID));

                request.append(buildEndTag(GPON_PONLINK_PORT));
                request.append(buildEndTag(GPON_PONLINK_PORTS));
            } else {
                request.append(buildEmptyTag(GPON_PONLINK_PORTS));
            }
            request.append(buildEndTag(VOLT_PORTS));
            request.append(VOLT_NE_CLOSE);

            reply = controller
                        .getDevicesMap()
                        .get(ncDeviceId)
                        .getSession()
                        .get(request.toString(), REPORT_ALL);
        } catch (IOException e) {
            log.error("Cannot communicate to device {} exception {}", ncDeviceId, e);
        }
        return reply;
    }

    @Override
    public boolean setPonLink(String target) {
        DriverHandler handler = handler();
        NetconfController controller = handler.get(NetconfController.class);
        MastershipService mastershipService = handler.get(MastershipService.class);
        DeviceId ncDeviceId = handler.data().deviceId();
        checkNotNull(controller, "Netconf controller is null");

        if (!mastershipService.isLocalMaster(ncDeviceId)) {
            log.warn("Not master for {} Use {} to execute command",
                     ncDeviceId,
                     mastershipService.getMasterFor(ncDeviceId));
            return false;
        }

        String[] data = checkSetInput(target);
        if (data == null) {
            log.error("Failed to check input: {}", target);
            return false;
        }

        boolean result = false;
        try {
            StringBuilder request = new StringBuilder();
            request.append(VOLT_NE_OPEN).append(VOLT_NE_NAMESPACE);
            request.append(ANGLE_RIGHT).append(NEW_LINE);
            request.append(buildStartTag(VOLT_PORTS));
            request.append(buildStartTag(GPON_PONLINK_PORTS));
            request.append(buildStartTag(GPON_PONLINK_PORT));
            request.append(buildStartTag(PONLINK_ID, false));
            request.append(data[FIRST_PART]);
            request.append(buildEndTag(PONLINK_ID));

            request.append(buildStartTag(data[SECOND_PART], false));
            request.append(data[THIRD_PART]);
            request.append(buildEndTag(data[SECOND_PART]));

            request.append(buildEndTag(GPON_PONLINK_PORT));
            request.append(buildEndTag(GPON_PONLINK_PORTS));
            request.append(buildEndTag(VOLT_PORTS));
            request.append(VOLT_NE_CLOSE);

            result = controller.getDevicesMap().get(ncDeviceId).getSession().
                    editConfig(RUNNING, null, request.toString());
        } catch (IOException e) {
            log.error("Cannot communicate to device {} exception {}", ncDeviceId, e);
        }
        return result;
    }

    /**
     * Verifies input string for valid options.
     *
     * @param target input data in string
     * @return String array
     * @return null if an error condition is detected
     */
    private String[] checkSetInput(String target) {
        String[] data = target.split(COLON);
        String paramName = data[SECOND_PART];
        String paramValue = data[THIRD_PART];
        int pon;

        if (data.length != THREE) {
            log.error("Invalid number of arguments {}", data.length);
            return null;
        }

        try {
            pon = Integer.parseInt(data[FIRST_PART]);
            if (pon <= ZERO) {
                log.error("Invalid integer for ponlink-id: {}",
                          data[FIRST_PART]);
                return null;
            }
        } catch (NumberFormatException e) {
            log.error("Non-number input for ponlink-id: {}",
                      data[FIRST_PART]);
            return null;
        }

        if (!PON_LINK_PARAMS.containsKey(paramName)) {
            log.error("Unsupported parameter: {}", paramName);
            return null;
        }

        List<Integer> range = PON_LINK_PARAMS.get(paramName);
        if (range == null) {
            switch (paramName) {
                case ADMIN_STATE:
                    if (!validState(ADMINSTATES, paramName, paramValue)) {
                        return null;
                    }
                    break;
                case ONU_DISCOVERY_MODE:
                    if (!validState(ONUDISCOVERYMODES, paramName, paramValue)) {
                        return null;
                    }
                    break;
                default:
                    if (!validState(PMENABLES, paramName, paramValue)) {
                        return null;
                    }
                    break;
            }
        } else {
            int value;

            try {
                value = Integer.parseInt(paramValue);
            } catch (NumberFormatException e) {
                log.error("Non-number input for Name {} : Value {}.",
                          paramName, paramValue);
                return null;
            }

            if ((value < range.get(RANGE_MIN)) ||
                (value > range.get(RANGE_MAX))) {
                log.error("Out of value range for Name {} : Value {}.",
                          paramName, paramValue);
                return null;
            }
        }

        return data;
    }

    /**
     * Verifies input string for valid options.
     *
     * @param states input data in string for parameter state
     * @param name input data in string for parameter name
     * @param value input data in string for parameter value
     * @return true if the param is valid
     * @return false if the param is invalid
     */
    private boolean validState(Set<String> states, String name, String value) {
        if (!states.contains(value)) {
            log.error("Invalid value for Name {} : Value {}.", name, value);
            return false;
        }
        return true;
    }
}
