/*
 * 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 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 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 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()));
    }
}
