/*
 * Copyright 2015-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;

import com.google.common.collect.Multimap;
import org.apache.commons.lang3.NotImplementedException;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flowobjective.NextObjective;
import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
import org.onosproject.segmentrouting.grouphandler.NextNeighbors;
import org.onosproject.segmentrouting.mcast.McastFilteringObjStoreKey;
import org.onosproject.segmentrouting.mcast.McastRole;
import org.onosproject.segmentrouting.mcast.McastRoleStoreKey;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
import org.onosproject.segmentrouting.pwaas.L2Tunnel;
import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;

import com.google.common.collect.ImmutableMap;
import org.onosproject.segmentrouting.mcast.McastStoreKey;
import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
import org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey;
import org.onosproject.segmentrouting.storekey.MacVlanNextObjectiveStoreKey;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * Segment Routing Service for REST API.
 */
public interface SegmentRoutingService {
    /**
     * VLAN cross-connect ACL priority.
     *
     * @deprecated in ONOS 1.12. Replaced by {@link org.onosproject.segmentrouting.xconnect.api.XconnectService}
     */
    @Deprecated
    int XCONNECT_ACL_PRIORITY = 60000;

    /**
     * VLAN cross-connect Bridging priority.
     *
     * @deprecated in ONOS 1.12. Replaced by {@link org.onosproject.segmentrouting.xconnect.api.XconnectService}
     */
    @Deprecated
    int XCONNECT_PRIORITY = 1000;

    /**
     * Default flow priority.
     */
    int DEFAULT_PRIORITY = 100;

    /**
     * Minimum IP priority.
     *
     * Should &lt; 0 such that priority of /0 will not conflict with lowest
     * priority default entries.
     */
    int MIN_IP_PRIORITY = 10;

    /**
     * Subnet flooding flow priority.
     */
    int FLOOD_PRIORITY = 5;

    /**
     * Returns all tunnels.
     *
     * @return list of tunnels
     */
    List<Tunnel> getTunnels();

    /**
     * Creates a tunnel.
     *
     * @param tunnel tunnel reference to create
     * @return WRONG_PATH if the tunnel path is wrong, ID_EXISTS if the tunnel ID
     * exists already, TUNNEL_EXISTS if the same tunnel exists, INTERNAL_ERROR
     * if the tunnel creation failed internally, SUCCESS if the tunnel is created
     * successfully
     */
    TunnelHandler.Result createTunnel(Tunnel tunnel);

    /**
     * Returns all policies.
     *
     * @return list of policy
     */
    List<Policy> getPolicies();

    /**
     * Returns the l2 tunnel descriptions.
     *
     * @param pending if true fetch pending pseudowires, else fetch installed
     * @return set of l2 tunnel descriptions.
     */
    Set<L2TunnelDescription> getL2TunnelDescriptions(boolean pending);

    /**
     * Returns all l2 tunnels of pseudowires.
     *
     * @return list of l2 tunnels
     */
    List<L2Tunnel> getL2Tunnels();

    /**
     * Returns all l2 policie of pseudowires.
     *
     * @return list of l2 policies.
     */
    List<L2TunnelPolicy> getL2Policies();

    /**
     * Removes pseudowire.
     *
     * @param pwId The id of the pseudowire.
     * @return SUCCESS if operation successful or a descriptive error otherwise.
     */
    L2TunnelHandler.Result removePseudowire(Integer pwId);

    /**
     * Adds a Pseudowire to the system.
     *
     * @param tunnel The pseudowire tunnel.
     * @return SUCCESS if operation is successful or a descriptive error otherwise.
     */
    L2TunnelHandler.Result addPseudowire(L2TunnelDescription tunnel);

    /**
     * Adds a set of pseudowires.
     *
     *
     * @param l2TunnelDescriptions The pseudowires to add.
     * @return SUCCESS if ALL pseudowires can be instantiated and are deployed, or a
     *         a descriptive error otherwise, without deploying any pseudowire.
     * @deprecated onos-1.12 use addPseudowire instead
     */
    @Deprecated
    L2TunnelHandler.Result addPseudowiresBulk(List<DefaultL2TunnelDescription> l2TunnelDescriptions);

    /**
     * Creates a policy.
     *
     * @param policy policy reference to create
     * @return ID_EXISTS if the same policy ID exists,
     *  POLICY_EXISTS if the same policy exists, TUNNEL_NOT_FOUND if the tunnel
     *  does not exists, UNSUPPORTED_TYPE if the policy type is not supported,
     *  SUCCESS if the policy is created successfully.
     */
    PolicyHandler.Result createPolicy(Policy policy);

    /**
     * Removes a tunnel.
     *
     * @param tunnel tunnel reference to remove
     * @return TUNNEL_NOT_FOUND if the tunnel to remove does not exists,
     * INTERNAL_ERROR if the tunnel creation failed internally, SUCCESS
     * if the tunnel is created successfully.
     */
    TunnelHandler.Result removeTunnel(Tunnel tunnel);

    /**
     * Removes a policy.
     *
     * @param policy policy reference to remove
     * @return POLICY_NOT_FOUND if the policy to remove does not exists,
     * SUCCESS if it is removed successfully
     */
    PolicyHandler.Result removePolicy(Policy policy);

    /**
     * Use current state of the network to repopulate forwarding rules.
     *
     */
    void rerouteNetwork();

    /**
     * Returns device-subnet mapping.
     *
     * @return device-subnet mapping
     */
    Map<DeviceId, Set<IpPrefix>> getDeviceSubnetMap();

    /**
     * Returns the current ECMP shortest path graph in this controller instance.
     *
     * @return ECMP shortest path graph
     */
    ImmutableMap<DeviceId, EcmpShortestPathGraph> getCurrentEcmpSpg();

    /**
     * Returns the destinatiomSet-NextObjective store contents.
     *
     * @return current contents of the dstNextObjStore
     */
    ImmutableMap<DestinationSetNextObjectiveStoreKey, NextNeighbors> getDstNextObjStore();

    /**
     * Returns the VLAN next objective store.
     *
     * @return current contents of the vlanNextObjStore
     */
    ImmutableMap<VlanNextObjectiveStoreKey, Integer> getVlanNextObjStore();

    /**
     * Returns the Mac Vlan next objective store.
     *
     * @return current contents of the macVlanNextObjStore
     */
    ImmutableMap<MacVlanNextObjectiveStoreKey, Integer> getMacVlanNextObjStore();

    /**
     * Returns the port next objective store.
     *
     * @return current contents of the portNextObjStore
     */
    ImmutableMap<PortNextObjectiveStoreKey, Integer> getPortNextObjStore();

    /**
     * Returns the associated next ids to the mcast groups or to the single
     * group if mcastIp is present.
     *
     * @param mcastIp the group ip
     * @return the mapping mcastIp-device to next id
     */
    Map<McastStoreKey, Integer> getMcastNextIds(IpAddress mcastIp);

    /**
     * Returns the PW init next objective store.
     *
     * @return current contents of the l2InitiationNextObjStore
     */
    ImmutableMap<String, NextObjective> getPwInitNext();

    /**
     * Returns the PW termination next objective store.
     *
     * @return current contents of the l2TerminationNextObjStore
     */
    ImmutableMap<String, NextObjective> getPwTermNext();

    /**
     * Removes all entries in dst/vlan/port/mcast NextObjectiveStore that are associated with the given nextId.
     *
     * @param nextId nextId
     */
    void invalidateNextObj(int nextId);

    /**
     * Triggers the verification of all ECMP groups in the specified device.
     * Adjusts the group buckets if verification finds that there are more or less
     * buckets than what should be there.
     *
     * @param id the device identifier
     */
    void verifyGroups(DeviceId id);

    /**
     * Returns the internal link state as seen by this instance of the
     * controller.
     *
     * @return the internal link state
     */
    ImmutableMap<Link, Boolean> getSeenLinks();

    /**
     * Returns the ports administratively disabled by the controller.
     *
     * @return a map of devices and port numbers for administratively disabled
     *         ports. Does not include ports manually disabled by the operator.
     */
    ImmutableMap<DeviceId, Set<PortNumber>> getDownedPortState();

    /**
     * Returns the associated roles to the mcast groups.
     *
     * @param mcastIp the group ip
     * @param sourcecp the source connect point
     * @return the mapping mcastIp-device to mcast role
     */
    Map<McastRoleStoreKey, McastRole> getMcastRoles(IpAddress mcastIp,
                                                    ConnectPoint sourcecp);

    /**
     * Returns the associated trees to the mcast group.
     *
     * @param mcastIp the group ip
     * @param sourcecp the source connect point
     * @return the mapping egress point to mcast path
     */
    Multimap<ConnectPoint, List<ConnectPoint>> getMcastTrees(IpAddress mcastIp,
                                                             ConnectPoint sourcecp);

    /**
     * Return the leaders of the mcast groups.
     *
     * @param mcastIp the group ip
     * @return the mapping group-node
     */
    Map<IpAddress, NodeId> getMcastLeaders(IpAddress mcastIp);

    /**
     * Returns shouldProgram map.
     *
     * @return shouldProgram map
     */
    Map<Set<DeviceId>, NodeId> getShouldProgram();

    /**
     * Returns shouldProgram local cache.
     *
     * @return shouldProgram local cache
     */
    Map<DeviceId, Boolean> getShouldProgramCache();

    /**
     * Returns whether instance should program device or not.
     *
     * @param deviceId .
     * @return boolean status saying instance should program device or not.
     */
    boolean shouldProgram(DeviceId deviceId);

    /**
     * Returns the mcast filtering obj.
     *
     * @return the mapping group-node
     */
    Map<DeviceId, List<McastFilteringObjStoreKey>> getMcastFilters();

    /**
     * Determines if routing in the network has been stable in the last
     * STABILITY_THRESHOLD seconds, by comparing the current time to the last
     * routing change timestamp.
     *
     * @return true if stable
     */
    boolean isRoutingStable();

    /**
     * Invoke hostHandler.init() for given device.
     *
     * @param deviceId device ID
     */
    void initHost(DeviceId deviceId);

    /**
     * Invoke routeHandler.init() for given device.
     *
     * @param deviceId device ID
     */
    void initRoute(DeviceId deviceId);

    /**
     * Gets application id.
     *
     * @return application id
     */
    default ApplicationId appId() {
        throw new NotImplementedException("appId not implemented");
    }

    /**
     * Returns internal VLAN for untagged hosts on given connect point.
     * <p>
     * The internal VLAN is either vlan-untagged for an access port,
     * or vlan-native for a trunk port.
     *
     * @param connectPoint connect point
     * @return internal VLAN or null if both vlan-untagged and vlan-native are undefined
     */
    default VlanId getInternalVlanId(ConnectPoint connectPoint) {
        throw new NotImplementedException("getInternalVlanId not implemented");
    }

    /**
     * Returns optional pair device ID of given device.
     *
     * @param deviceId device ID
     * @return optional pair device ID. Might be empty if pair device is not configured
     */
    default Optional<DeviceId> getPairDeviceId(DeviceId deviceId) {
        throw new NotImplementedException("getPairDeviceId not implemented");
    }

    /**
     * Returns optional pair device local port of given device.
     *
     * @param deviceId device ID
     * @return optional pair device ID. Might be empty if pair device is not configured
     */
    default Optional<PortNumber> getPairLocalPort(DeviceId deviceId) {
        throw new NotImplementedException("getPairLocalPort not implemented");
    }

    /**
     * Returns a set of infrastructure ports on the given device.
     *
     * @param deviceId device ID
     * @return a set of ports that does not have interface configuration
     */
    default Set<PortNumber> getInfraPorts(DeviceId deviceId) {
        throw new NotImplementedException("getInfraPorts not implemented");
    }

    /**
     * Returns a set of edge ports on the given device.
     *
     * @param deviceId device ID
     * @return a set of ports that has interface configuration
     */
    default Set<PortNumber> getEdgePorts(DeviceId deviceId) {
        throw new NotImplementedException("getEdgePorts not implemented");
    }

    /**
     * Returns a list of edge devices.
     *
     * @return list of the edge device ids
     */
    List<DeviceId> getEdgeDeviceIds();

    /**
     * Returns a list of infra devices.
     *
     * @return list of the infra device ids
     */
    List<DeviceId> getInfraDeviceIds();

    /**
     * Returns the configured mac address of the device.
     *
     * @param deviceId the device id
     * @return the configured mac address
     * @throws DeviceConfigNotFoundException if config is not present
     */
    MacAddress getDeviceMacAddress(DeviceId deviceId) throws DeviceConfigNotFoundException;

    /**
     * Returns the VlanId assigned internally by default to unconfigured ports.
     *
     * @return the default internal vlan id
     */
    VlanId getDefaultInternalVlan();
}
