/*
 * 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.onosproject.evpnopenflow.rsc.vpnport.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.evpnopenflow.rsc.BasePort;
import org.onosproject.evpnopenflow.rsc.BasePortId;
import org.onosproject.evpnopenflow.rsc.DefaultVpnPort;
import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
import org.onosproject.evpnopenflow.rsc.VpnPort;
import org.onosproject.evpnopenflow.rsc.VpnPortId;
import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortEvent;
import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortListener;
import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
import org.onosproject.net.DeviceId;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.AllocationPool;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultSubnet;
import org.onosproject.vtnrsc.DefaultTenantNetwork;
import org.onosproject.vtnrsc.DefaultVirtualPort;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.HostRoute;
import org.onosproject.vtnrsc.PhysicalNetwork;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.Subnet;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVENT_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_PORT_START;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_PORT_STOP;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INTERFACE_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_CREATION_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_DELETE_FAILED;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_ID_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_IS_NOT_EXIST;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_STORE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_UPDATE_FAILED;

/**
 * Provides implementation of the VpnPort service.
 */
@Component(immediate = true)
@Service
public class VpnPortManager implements VpnPortService {

    private final Logger log = LoggerFactory.getLogger(getClass());
    private final Set<VpnPortListener> listeners = Sets
            .newCopyOnWriteArraySet();

    protected EventuallyConsistentMap<VpnPortId, VpnPort> vpnPortStore;
    protected ApplicationId appId;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected StorageService storageService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected BasePortService basePortService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VirtualPortService virtualPortService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected TenantNetworkService tenantNetworkService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected SubnetService subnetService;

    @Activate

    public void activate() {
        appId = coreService.registerApplication(APP_ID);
        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
                .register(KryoNamespaces.API).register(VpnPort.class)
                .register(VpnPortId.class);
        vpnPortStore = storageService
                .<VpnPortId, VpnPort>eventuallyConsistentMapBuilder()
                .withName(VPN_PORT_STORE).withSerializer(serializer)
                .withTimestampProvider((k, v) -> new WallClockTimestamp())
                .build();
        log.info(EVPN_VPN_PORT_START);
    }

    @Deactivate
    public void deactivate() {
        vpnPortStore.destroy();
        log.info(EVPN_VPN_PORT_STOP);
    }

    @Override
    public boolean exists(VpnPortId vpnPortId) {
        checkNotNull(vpnPortId, VPN_PORT_ID_NOT_NULL);
        return vpnPortStore.containsKey(vpnPortId);
    }

    @Override
    public VpnPort getPort(VpnPortId vpnPortId) {
        checkNotNull(vpnPortId, VPN_PORT_ID_NOT_NULL);
        return vpnPortStore.get(vpnPortId);
    }

    @Override
    public Collection<VpnPort> getPorts() {
        return Collections.unmodifiableCollection(vpnPortStore.values());
    }

    @Override
    public boolean createPorts(Iterable<VpnPort> vpnPorts) {
        checkNotNull(vpnPorts, VPN_PORT_NOT_NULL);
        for (VpnPort vpnPort : vpnPorts) {
            log.info(VPN_PORT_ID, vpnPort.id().toString());
            vpnPortStore.put(vpnPort.id(), vpnPort);
            if (!vpnPortStore.containsKey(vpnPort.id())) {
                log.info(VPN_PORT_CREATION_FAILED, vpnPort.id().toString());
                return false;
            }
            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_SET,
                                             vpnPort));
        }
        return true;
    }

    @Override
    public boolean updatePorts(Iterable<VpnPort> vpnPorts) {
        checkNotNull(vpnPorts, VPN_PORT_NOT_NULL);
        for (VpnPort vpnPort : vpnPorts) {
            if (!vpnPortStore.containsKey(vpnPort.id())) {
                log.info(VPN_PORT_IS_NOT_EXIST, vpnPort.id().toString());
                return false;
            }
            vpnPortStore.put(vpnPort.id(), vpnPort);
            if (!vpnPort.equals(vpnPortStore.get(vpnPort.id()))) {
                log.info(VPN_PORT_UPDATE_FAILED, vpnPort.id().toString());
                return false;
            }
            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_UPDATE,
                                             vpnPort));
        }
        return true;
    }

    @Override
    public boolean removePorts(Iterable<VpnPortId> vpnPortIds) {
        checkNotNull(vpnPortIds, VPN_PORT_NOT_NULL);
        for (VpnPortId vpnPortid : vpnPortIds) {
            VpnPort vpnPort = vpnPortStore.get(vpnPortid);
            vpnPortStore.remove(vpnPortid);
            if (vpnPortStore.containsKey(vpnPortid)) {
                log.info(VPN_PORT_DELETE_FAILED, vpnPortid.toString());
                return false;
            }
            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_DELETE,
                                             vpnPort));
        }
        return true;
    }

    @Override
    public void processGluonConfig(String action, String key, JsonNode value) {
        Collection<VpnPort> vpnPorts;
        switch (action) {
            case DELETE:
                String[] list = key.split(SLASH);
                VpnPortId vpnPortId
                        = VpnPortId.vpnPortId(list[list.length - 1]);
                Set<VpnPortId> vpnPortIds = Sets.newHashSet(vpnPortId);
                removePorts(vpnPortIds);
                // After removing vpn port and also remove virtual port from vtn
                VirtualPortId virtualPortId
                        = VirtualPortId.portId(list[list.length - 1]);
                Set<VirtualPortId> virtualPortIds
                        = Sets.newHashSet(virtualPortId);
                virtualPortService.removePorts(virtualPortIds);
                break;
            case SET:
                checkNotNull(value, RESPONSE_NOT_NULL);
                vpnPorts = changeJsonToSub(value);
                createPorts(vpnPorts);
                break;
            case UPDATE:
                checkNotNull(value, RESPONSE_NOT_NULL);
                vpnPorts = changeJsonToSub(value);
                updatePorts(vpnPorts);
                break;
            default:
                log.info("Invalid action is received while processing VPN " +
                                 "port configuration");
        }
    }

    /**
     * Creates dummy gluon network to the VTN.
     *
     * @param state        the base port state
     * @param adminStateUp the base port admin status
     * @param tenantID     the base port tenant ID
     */
    private void createDummyGluonNetwork(boolean adminStateUp, String state,
                                         TenantId tenantID) {
        String id = "11111111-1111-1111-1111-111111111111";
        String name = "GluonNetwork";
        String segmentationID = "50";
        String physicalNetwork = "None";

        TenantNetwork network = new DefaultTenantNetwork(TenantNetworkId.networkId(id), name,
                                                         adminStateUp,
                                                         TenantNetwork.State.valueOf(state),
                                                         false, tenantID,
                                                         false,
                                                         TenantNetwork.Type.LOCAL,
                                                         PhysicalNetwork.physicalNetwork(physicalNetwork),
                                                         SegmentationId.segmentationId(segmentationID));

        Set<TenantNetwork> networksSet = Sets.newHashSet(network);
        tenantNetworkService.createNetworks(networksSet);
    }


    /**
     * Creates dummy gluon subnet to the VTN.
     *
     * @param tenantId the base port tenant ID
     */
    public void createDummySubnet(TenantId tenantId) {
        String id = "22222222-2222-2222-2222-222222222222";
        String subnetName = "GluonSubnet";
        String cidr = "0.0.0.0/0";
        String gatewayIp = "0.0.0.0";
        Set<HostRoute> hostRoutes = Sets.newHashSet();
        String ipV6AddressMode = null;
        String ipV6RaMode = null;
        TenantNetworkId tenantNetworkId = null;
        Set<AllocationPool> allocationPools = Sets.newHashSet();
        Iterable<TenantNetwork> networks
                = tenantNetworkService.getNetworks();

        for (TenantNetwork tenantNetwork : networks) {
            if (tenantNetwork.name().equals("GluonNetwork")) {
                tenantNetworkId = tenantNetwork.id();
                break;
            }
        }
        Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName,
                                          tenantNetworkId,
                                          tenantId, IpAddress.Version.INET,
                                          cidr == null ? null : IpPrefix.valueOf(cidr),
                                          gatewayIp == null ? null : IpAddress.valueOf(gatewayIp),
                                          false, false, hostRoutes,
                                          ipV6AddressMode == null ? null : Subnet.Mode.valueOf(ipV6AddressMode),
                                          ipV6RaMode == null ? null : Subnet.Mode.valueOf(ipV6RaMode),
                                          allocationPools);

        Set<Subnet> subnetsSet = Sets.newHashSet(subnet);
        subnetService.createSubnets(subnetsSet);
    }

    /**
     * Returns a collection of vpnPort from subnetNodes.
     *
     * @param vpnPortNodes the vpnPort json node
     * @return list of vpnports
     */
    private Collection<VpnPort> changeJsonToSub(JsonNode vpnPortNodes) {
        checkNotNull(vpnPortNodes, JSON_NOT_NULL);
        Map<VpnPortId, VpnPort> vpnPortMap = new HashMap<>();
        String interfaceId = vpnPortNodes.get(INTERFACE_ID).asText();
        VpnPortId vpnPortId = VpnPortId.vpnPortId(interfaceId);
        VpnInstanceId vpnInstanceId = VpnInstanceId
                .vpnInstanceId(vpnPortNodes.get(VPN_INSTANCE).asText());
        VpnPort vpnPort = new DefaultVpnPort(vpnPortId, vpnInstanceId);
        vpnPortMap.put(vpnPortId, vpnPort);
        // update ip address and tenant network information in vtn
        TenantNetworkId tenantNetworkId = null;
        Map<VirtualPortId, VirtualPort> vPortMap = new HashMap<>();
        BasePortId basePortId = BasePortId.portId(interfaceId);
        VirtualPortId virtualPortId = VirtualPortId.portId(interfaceId);
        BasePort bPort = basePortService.getPort(basePortId);
        if (bPort != null) {
            FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(basePortId.toString()),
                                              IpAddress.valueOf(vpnPortNodes
                                                                        .get("ipaddress").asText()));
            Set<FixedIp> fixedIps = new HashSet<>();
            fixedIps.add(fixedIp);
            Map<String, String> strMap = new HashMap<>();
            boolean adminStateUp = bPort.adminStateUp();
            strMap.put("name", bPort.name());
            strMap.put("deviceOwner", bPort.deviceOwner());
            strMap.put("bindingVnicType", bPort.bindingVnicType());
            strMap.put("bindingVifType", bPort.bindingVifType());
            strMap.put("bindingVifDetails", bPort.bindingVifDetails());
            String state = bPort.state();
            MacAddress macAddress = bPort.macAddress();
            TenantId tenantId = bPort.tenantId();
            DeviceId deviceId = bPort.deviceId();
            BindingHostId bindingHostId = bPort.bindingHostId();
            // Creates Dummy Gluon Network and Subnet
            createDummyGluonNetwork(adminStateUp, state, tenantId);
            createDummySubnet(tenantId);

            Iterable<TenantNetwork> networks
                    = tenantNetworkService.getNetworks();

            for (TenantNetwork tenantNetwork : networks) {
                if (tenantNetwork.name().equals("GluonNetwork")) {
                    tenantNetworkId = tenantNetwork.id();
                    break;
                }
            }
            if (tenantNetworkId != null) {

                DefaultVirtualPort vPort = new DefaultVirtualPort(virtualPortId,
                                                                  tenantNetworkId,
                                                                  adminStateUp,
                                                                  strMap, isState(state),
                                                                  macAddress, tenantId,
                                                                  deviceId, fixedIps,
                                                                  bindingHostId,
                                                                  null,
                                                                  null);
                vPortMap.put(virtualPortId, vPort);
                Collection<VirtualPort> virtualPorts
                        = Collections.unmodifiableCollection(vPortMap.values());
                virtualPortService.createPorts(virtualPorts);
            }
        }

        return Collections.unmodifiableCollection(vpnPortMap.values());
    }

    /**
     * Returns BasePort State.
     *
     * @param state the base port state
     * @return the basePort state
     */
    private VirtualPort.State isState(String state) {
        if (state.equals("ACTIVE")) {
            return VirtualPort.State.ACTIVE;
        } else {
            return VirtualPort.State.DOWN;
        }

    }

    @Override
    public void addListener(VpnPortListener listener) {
        checkNotNull(listener, LISTENER_NOT_NULL);
        listeners.add(listener);
    }

    @Override
    public void removeListener(VpnPortListener listener) {
        checkNotNull(listener, LISTENER_NOT_NULL);
        listeners.remove(listener);
    }

    /**
     * Notifies specify event to all listeners.
     *
     * @param event Vpn Port event
     */
    private void notifyListeners(VpnPortEvent event) {
        checkNotNull(event, EVENT_NOT_NULL);
        listeners.forEach(listener -> {
            listener.event(event);
        });
    }
}
