/*
 * 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 FIRST_PART = 0;
    private static final int SECOND_PART = 1;
    private static final int THIRD_PART = 2;
    private static final int RANGE_MIN = 0;
    private static final int RANGE_MAX = 1;
    private static final int ZERO = 0;
    private static final int THREE = 3;

    @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 reply;
        }

        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 reply;
                    }
                } catch (NumberFormatException e) {
                    log.error("Non-number input for ponlink-id:{}", target);
                    return reply;
                }
                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;
    }
}
