/*
 * Copyright 2017-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.opencord.igmpproxy.impl;

import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.basics.BasicElementConfig;

/**
 * Net configuration class for igmpproxy.
 */
public class IgmpproxyConfig extends Config<ApplicationId> {
    protected static final String DEFAULT_UNSOLICITED_TIMEOUT = "2";
    protected static final String DEFAULT_MAX_RESP = "10";
    protected static final String DEFAULT_KEEP_ALIVE_INTERVAL = "120";
    protected static final String DEFAULT_KEEP_ALIVE_COUNT = "3";
    protected static final String DEFAULT_LAST_QUERY_INTERVAL = "2";
    protected static final String DEFAULT_LAST_QUERY_COUNT = "2";
    protected static final String DEFAULT_IGMP_COS = "7";
    protected static final String DEFAULT_UNI_IGMP_COS = "7";
    protected static final Boolean DEFAULT_FAST_LEAVE = false;
    protected static final Boolean DEFAULT_PERIODIC_QUERY = true;
    protected static final String DEFAULT_WITH_RA_UPLINK = "true";
    protected static final String DEFAULT_WITH_RA_DOWNLINK = "true";
    private static final Boolean DEFAULT_CONNECT_POINT_MODE = true;
    private static final Boolean DEFAULT_PIMSSM_INTERWORKING = false;
    private static final Boolean DEFAULT_IGMP_PROVISIONING_SUPPORT = Boolean.FALSE;
    private static final Boolean DEFAULT_IGMP_ON_POD_BASIS = Boolean.FALSE;
    private static final Boolean DEFAULT_OUTGOING_IGMP_WITH_V3 = Boolean.TRUE;

    protected static final String CONNECT_POINT_MODE = "globalConnectPointMode";
    protected static final String CONNECT_POINT = "globalConnectPoint";
    private static final String UNSOLICITED_TIMEOUT = "UnsolicitedTimeOut";
    private static final String MAX_RESP = "MaxResp";
    private static final String KEEP_ALIVE_INTERVAL = "KeepAliveInterval";
    private static final String KEEP_ALIVE_COUNT = "KeepAliveCount";
    private static final String LAST_QUERY_INTERVAL = "LastQueryInterval";
    private static final String LAST_QUERY_COUNT = "LastQueryCount";
    private static final String FAST_LEAVE = "FastLeave";
    private static final String PERIODIC_QUERY = "PeriodicQuery";
    private static final String IGMP_COS = "IgmpCos";
    private static final String IGMP_UNI_COS = "IgmpUniCos";
    private static final String WITH_RA_UPLINK = "withRAUpLink";
    private static final String WITH_RA_DOWN_LINK = "withRADownLink";
    private static final String PIMSSM_INTERWORKING = "pimSSmInterworking";
    private static final String SOURCE_DEV_PORT = "sourceDeviceAndPort";
    private static final String ENABLE_IGMP_PROVISIONING = "enableIgmpProvisioning";
    private static final String IGMP_ON_POD_BASIS = "igmpOnPodBasis";
    private static final String OUTGOING_IGMP_WITH_V3 = "outgoingIgmpWithV3";

    /**
     * Gets the value of a string property, protecting for an empty
     * JSON object.
     *
     * @param name name of the property
     * @param defaultValue default value if none has been specified
     * @return String value if one os found, default value otherwise
     */
    private String getStringProperty(String name, String defaultValue) {
        if (object == null) {
            return defaultValue;
        }
        return get(name, defaultValue);
    }

    public int unsolicitedTimeOut() {
        return Integer.parseInt(getStringProperty(UNSOLICITED_TIMEOUT, DEFAULT_UNSOLICITED_TIMEOUT));
    }

    public BasicElementConfig unsolicitedTimeOut(int timeout) {
        return (BasicElementConfig) setOrClear(UNSOLICITED_TIMEOUT, timeout);
    }

    public int maxResp() {
        return Integer.parseInt(getStringProperty(MAX_RESP, DEFAULT_MAX_RESP));
    }

    public BasicElementConfig maxResp(int maxResp) {
        return (BasicElementConfig) setOrClear(MAX_RESP, maxResp);
    }

    public int keepAliveInterval() {
        return Integer.parseInt(getStringProperty(KEEP_ALIVE_INTERVAL, DEFAULT_KEEP_ALIVE_INTERVAL));
    }

    public BasicElementConfig keepAliveInterval(int interval) {
        return (BasicElementConfig) setOrClear(KEEP_ALIVE_INTERVAL, interval);
    }

    public int keepAliveCount() {
        return Integer.parseInt(getStringProperty(KEEP_ALIVE_COUNT, DEFAULT_KEEP_ALIVE_COUNT));
    }

    public BasicElementConfig keepAliveCount(int count) {
        return (BasicElementConfig) setOrClear(KEEP_ALIVE_COUNT, count);
    }

    public int lastQueryInterval() {
        return Integer.parseInt(getStringProperty(LAST_QUERY_INTERVAL, DEFAULT_LAST_QUERY_INTERVAL));
    }

    public BasicElementConfig lastQueryInterval(int interval) {
        return (BasicElementConfig) setOrClear(LAST_QUERY_INTERVAL, interval);
    }

    public int lastQueryCount() {
        return Integer.parseInt(getStringProperty(LAST_QUERY_COUNT, DEFAULT_LAST_QUERY_COUNT));
    }

    public BasicElementConfig lastQueryCount(int count) {
        return (BasicElementConfig) setOrClear(LAST_QUERY_COUNT, count);
    }

    public boolean fastLeave() {
        if (object == null || object.path(FAST_LEAVE) == null) {
            return DEFAULT_FAST_LEAVE;
        }
        return Boolean.parseBoolean(getStringProperty(FAST_LEAVE, DEFAULT_FAST_LEAVE.toString()));
    }

    public BasicElementConfig fastLeave(boolean fastLeave) {
        return (BasicElementConfig) setOrClear(FAST_LEAVE, fastLeave);
    }

    public boolean periodicQuery() {
        if (object == null || object.path(PERIODIC_QUERY) == null) {
            return DEFAULT_PERIODIC_QUERY;
        }
        return Boolean.parseBoolean(getStringProperty(PERIODIC_QUERY, DEFAULT_PERIODIC_QUERY.toString()));
    }

    public BasicElementConfig periodicQuery(boolean periodicQuery) {
        return (BasicElementConfig) setOrClear(PERIODIC_QUERY, periodicQuery);
    }

    public byte igmpCos() {
        return Byte.parseByte(getStringProperty(IGMP_COS, DEFAULT_IGMP_COS));
    }

    public byte igmpUniCos() {
        return Byte.parseByte(getStringProperty(IGMP_UNI_COS, DEFAULT_UNI_IGMP_COS));
    }

    public boolean withRAUplink() {
        if (object == null || object.path(WITH_RA_UPLINK) == null) {
            return true;
        }
        return Boolean.parseBoolean(getStringProperty(WITH_RA_UPLINK, DEFAULT_WITH_RA_UPLINK));
    }

    public boolean withRADownlink() {
        if (object == null || object.path(WITH_RA_DOWN_LINK) == null) {
            return false;
        }
        return Boolean.parseBoolean(getStringProperty(WITH_RA_DOWN_LINK, DEFAULT_WITH_RA_DOWNLINK));
    }

    public boolean connectPointMode() {
        if (object == null || object.path(CONNECT_POINT_MODE) == null) {
            return DEFAULT_CONNECT_POINT_MODE;
        }
        return Boolean.parseBoolean(getStringProperty(CONNECT_POINT_MODE, DEFAULT_CONNECT_POINT_MODE.toString()));
    }

    public ConnectPoint connectPoint() {
        if (object == null || object.path(CONNECT_POINT) == null) {
            return null;
        }

        try {
            return ConnectPoint.deviceConnectPoint(getStringProperty(CONNECT_POINT, ""));
        } catch (Exception ex) {
            return null;
        }
    }

    public boolean pimSsmInterworking() {
        if (object == null || object.path(PIMSSM_INTERWORKING) == null) {
            return DEFAULT_PIMSSM_INTERWORKING;
        }
        return Boolean.parseBoolean(getStringProperty(PIMSSM_INTERWORKING, DEFAULT_PIMSSM_INTERWORKING.toString()));
    }

    public ConnectPoint getSourceDeviceAndPort() {
        if (object == null || object.path(SOURCE_DEV_PORT) == null) {
            return null;
        }

        try {
            return ConnectPoint.deviceConnectPoint(getStringProperty(SOURCE_DEV_PORT, ""));
        } catch (Exception ex) {
            return null;
        }
    }

    public boolean enableIgmpProvisioning() {
        if (object == null || object.path(ENABLE_IGMP_PROVISIONING) == null) {
            return DEFAULT_IGMP_PROVISIONING_SUPPORT;
        }
        return Boolean.parseBoolean(getStringProperty(ENABLE_IGMP_PROVISIONING,
                                                      DEFAULT_IGMP_PROVISIONING_SUPPORT.toString()));
    }

    public boolean igmpOnPodBasis() {
        if (object == null || object.path(IGMP_ON_POD_BASIS) == null) {
            return DEFAULT_IGMP_ON_POD_BASIS;
        }
        return Boolean.parseBoolean(getStringProperty(IGMP_ON_POD_BASIS,
                                                      DEFAULT_IGMP_ON_POD_BASIS.toString()));
    }

    public Boolean outgoingIgmpWithV3() {
        if (object == null || object.path(OUTGOING_IGMP_WITH_V3) == null) {
            return null;
        }
        return Boolean.parseBoolean(getStringProperty(OUTGOING_IGMP_WITH_V3, DEFAULT_OUTGOING_IGMP_WITH_V3.toString()));
    }
}
