/*
 * Copyright 2016-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.onosproject.segmentrouting.config;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.Config;

import java.util.Set;

import static com.google.common.base.MoreObjects.toStringHelper;

/**
 * App configuration object for Segment Routing.
 */
public class SegmentRoutingAppConfig extends Config<ApplicationId> {
    private static final String VROUTER_MACS = "vRouterMacs";
    private static final String SUPPRESS_SUBNET = "suppressSubnet";
    private static final String SUPPRESS_HOST_BY_PORT = "suppressHostByPort";
    // TODO We might want to move SUPPRESS_HOST_BY_PROVIDER to Component Config
    private static final String SUPPRESS_HOST_BY_PROVIDER = "suppressHostByProvider";
    private static final String MPLS_ECMP = "MPLS-ECMP";

    @Override
    public boolean isValid() {
        return hasOnlyFields(VROUTER_MACS, SUPPRESS_SUBNET,
                SUPPRESS_HOST_BY_PORT, SUPPRESS_HOST_BY_PROVIDER, MPLS_ECMP) &&
                vRouterMacs() != null &&
                suppressSubnet() != null && suppressHostByPort() != null &&
                suppressHostByProvider() != null;
    }

    /**
     * Gets MPLS-ECMP configuration from the config.
     *
     * @return the configuration of MPLS-ECMP. If it is not
     *         specified, the default behavior is false.
     */
    public boolean mplsEcmp() {
        return get(MPLS_ECMP, false);
    }

    /**
     * Sets MPLS-ECMP to the config.
     *
     * @param mplsEcmp the MPLS-ECMP configuration
     * @return this {@link SegmentRoutingAppConfig}
     */
    public SegmentRoutingAppConfig setMplsEcmp(boolean mplsEcmp) {
        object.put(MPLS_ECMP, mplsEcmp);
        return this;
    }

    /**
     * Gets vRouters from the config.
     *
     * @return Set of vRouter MAC addresses, empty is not specified,
     *         or null if not valid
     */
    public Set<MacAddress> vRouterMacs() {
        if (!object.has(VROUTER_MACS)) {
            return ImmutableSet.of();
        }

        ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder();
        ArrayNode arrayNode = (ArrayNode) object.path(VROUTER_MACS);
        for (JsonNode jsonNode : arrayNode) {
            MacAddress mac;

            String macStr = jsonNode.asText(null);
            if (macStr == null) {
                return null;
            }
            try {
                mac = MacAddress.valueOf(macStr);
            } catch (IllegalArgumentException e) {
                return null;
            }

            builder.add(mac);
        }
        return builder.build();
    }

    /**
     * Sets vRouters to the config.
     *
     * @param vRouterMacs a set of vRouter MAC addresses
     * @return this {@link SegmentRoutingAppConfig}
     */
    public SegmentRoutingAppConfig setVRouterMacs(Set<MacAddress> vRouterMacs) {
        if (vRouterMacs == null) {
            object.remove(VROUTER_MACS);
        } else {
            ArrayNode arrayNode = mapper.createArrayNode();

            vRouterMacs.forEach(mac -> {
                arrayNode.add(mac.toString());
            });

            object.set(VROUTER_MACS, arrayNode);
        }
        return this;
    }

    /**
     * Gets names of ports to which SegmentRouting does not push subnet rules.
     *
     * @return Set of port names, empty if not specified, or null
     *         if not valid
     */
    public Set<ConnectPoint> suppressSubnet() {
        if (!object.has(SUPPRESS_SUBNET)) {
            return ImmutableSet.of();
        }

        ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_SUBNET);
        for (JsonNode jsonNode : arrayNode) {
            String portName = jsonNode.asText(null);
            if (portName == null) {
                return null;
            }
            try {
                builder.add(ConnectPoint.deviceConnectPoint(portName));
            } catch (IllegalArgumentException e) {
                return null;
            }
        }
        return builder.build();
    }

    /**
     * Sets names of ports to which SegmentRouting does not push subnet rules.
     *
     * @param suppressSubnet names of ports to which SegmentRouting does not push
     *                     subnet rules
     * @return this {@link SegmentRoutingAppConfig}
     */
    public SegmentRoutingAppConfig setSuppressSubnet(Set<ConnectPoint> suppressSubnet) {
        if (suppressSubnet == null) {
            object.remove(SUPPRESS_SUBNET);
        } else {
            ArrayNode arrayNode = mapper.createArrayNode();
            suppressSubnet.forEach(connectPoint -> {
                arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
            });
            object.set(SUPPRESS_SUBNET, arrayNode);
        }
        return this;
    }

    /**
     * Gets connect points to which SegmentRouting does not push host rules.
     *
     * @return Set of connect points, empty if not specified, or null
     *         if not valid
     */
    public Set<ConnectPoint> suppressHostByPort() {
        if (!object.has(SUPPRESS_HOST_BY_PORT)) {
            return ImmutableSet.of();
        }

        ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PORT);
        for (JsonNode jsonNode : arrayNode) {
            String portName = jsonNode.asText(null);
            if (portName == null) {
                return null;
            }
            try {
                builder.add(ConnectPoint.deviceConnectPoint(portName));
            } catch (IllegalArgumentException e) {
                return null;
            }
        }
        return builder.build();
    }

    /**
     * Sets connect points to which SegmentRouting does not push host rules.
     *
     * @param connectPoints connect points to which SegmentRouting does not push
     *                     host rules
     * @return this {@link SegmentRoutingAppConfig}
     */
    public SegmentRoutingAppConfig setSuppressHostByPort(Set<ConnectPoint> connectPoints) {
        if (connectPoints == null) {
            object.remove(SUPPRESS_HOST_BY_PORT);
        } else {
            ArrayNode arrayNode = mapper.createArrayNode();
            connectPoints.forEach(connectPoint -> {
                arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
            });
            object.set(SUPPRESS_HOST_BY_PORT, arrayNode);
        }
        return this;
    }

    /**
     * Gets provider names from which SegmentRouting does not learn host info.
     *
     * @return array of provider names that need to be ignored
     */
    public Set<String> suppressHostByProvider() {
        if (!object.has(SUPPRESS_HOST_BY_PROVIDER)) {
            return ImmutableSet.of();
        }

        ImmutableSet.Builder<String> builder = ImmutableSet.builder();
        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PROVIDER);
        for (JsonNode jsonNode : arrayNode) {
            String providerName = jsonNode.asText(null);
            if (providerName == null) {
                return null;
            }
            builder.add(providerName);
        }
        return builder.build();
    }

    /**
     * Sets provider names from which SegmentRouting does not learn host info.
     *
     * @param providers set of provider names
     * @return this {@link SegmentRoutingAppConfig}
     */
    public SegmentRoutingAppConfig setSuppressHostByProvider(Set<String> providers) {
        if (providers == null) {
            object.remove(SUPPRESS_HOST_BY_PROVIDER);
        } else {
            ArrayNode arrayNode = mapper.createArrayNode();
            providers.forEach(arrayNode::add);
            object.set(SUPPRESS_HOST_BY_PROVIDER, arrayNode);
        }
        return this;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("vRouterMacs", vRouterMacs())
                .add("suppressSubnet", suppressSubnet())
                .add("suppressHostByPort", suppressHostByPort())
                .add("suppressHostByProvider", suppressHostByProvider())
                .add("mplsEcmp", mplsEcmp())
                .toString();
    }
}
