/*
 * 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.baseport.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.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.DefaultBasePort;
import org.onosproject.evpnopenflow.rsc.baseport.BasePortEvent;
import org.onosproject.evpnopenflow.rsc.baseport.BasePortListener;
import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.MultiValuedTimestamp;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultFloatingIp;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.FloatingIp;
import org.onosproject.vtnrsc.FloatingIpId;
import org.onosproject.vtnrsc.RouterId;
import org.onosproject.vtnrsc.SecurityGroup;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.TenantRouter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BASE_PORT_STORE;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;

/**
 * Provides implementation of the BasePort APIs.
 */
@Component(immediate = true)
@Service
public class BasePortManager implements BasePortService {

    private final Set<BasePortListener> listeners = Sets
            .newCopyOnWriteArraySet();
    private final Logger log = LoggerFactory.getLogger(getClass());
    private static final String BASEPORT_ID_NULL = "BasePort ID cannot be " +
            "null";
    private static final String BASEPORT_NOT_NULL = "BasePort  cannot be " +
            "null";
    private static final String TENANTID_NOT_NULL = "TenantId  cannot be null";
    private static final String NETWORKID_NOT_NULL = "NetworkId  cannot be null";
    private static final String DEVICEID_NOT_NULL = "DeviceId  cannot be null";
    private static final String FIXEDIP_NOT_NULL = "FixedIp  cannot be null";
    private static final String MAC_NOT_NULL = "Mac address  cannot be null";
    private static final String IP_NOT_NULL = "Ip  cannot be null";
    private static final String EVENT_NOT_NULL = "event cannot be null";
    private static final String SET = "set";
    private static final String UPDATE = "update";
    private static final String DELETE = "delete";
    private static final String SLASH = "/";
    private static final String PROTON_BASE_PORT = "Port";
    private static final String JSON_NOT_NULL = "JsonNode can not be null";

    protected EventuallyConsistentMap<BasePortId, BasePort> vPortStore;
    protected ApplicationId appId;

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

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

    @Activate
    public void activate() {

        appId = coreService.registerApplication(APP_ID);

        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
                .register(KryoNamespaces.API)
                .register(MultiValuedTimestamp.class)
                .register(TenantNetworkId.class)
                .register(Host.class)
                .register(TenantNetwork.class)
                .register(TenantNetworkId.class)
                .register(TenantId.class)
                .register(SubnetId.class)
                .register(BasePortId.class)
                .register(BasePort.State.class)
                .register(AllowedAddressPair.class)
                .register(FixedIp.class)
                .register(FloatingIp.class)
                .register(FloatingIpId.class)
                .register(FloatingIp.Status.class)
                .register(UUID.class)
                .register(DefaultFloatingIp.class)
                .register(BindingHostId.class)
                .register(SecurityGroup.class)
                .register(IpAddress.class)
                .register(DefaultBasePort.class)
                .register(RouterId.class)
                .register(TenantRouter.class)
                .register(BasePort.class);
        vPortStore = storageService
                .<BasePortId, BasePort>eventuallyConsistentMapBuilder()
                .withName(BASE_PORT_STORE).withSerializer(serializer)
                .withTimestampProvider((k, v) -> new WallClockTimestamp())
                .build();
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        vPortStore.destroy();
        log.info("Stoppped");
    }

    @Override
    public boolean exists(BasePortId vPortId) {
        checkNotNull(vPortId, BASEPORT_ID_NULL);
        return vPortStore.containsKey(vPortId);
    }

    @Override
    public BasePort getPort(BasePortId vPortId) {
        checkNotNull(vPortId, BASEPORT_ID_NULL);
        return vPortStore.get(vPortId);
    }

    @Override
    public BasePort getPort(FixedIp fixedIP) {
        checkNotNull(fixedIP, FIXEDIP_NOT_NULL);
        List<BasePort> vPorts = new ArrayList<>();
        vPortStore.values().forEach(p -> {
            for (FixedIp fixedIp : p.fixedIps()) {
                if (fixedIp.equals(fixedIP)) {
                    vPorts.add(p);
                    break;
                }
            }
        });
        if (vPorts.size() == 0) {
            return null;
        }
        return vPorts.get(0);
    }

    @Override
    public BasePort getPort(MacAddress mac) {
        checkNotNull(mac, MAC_NOT_NULL);
        List<BasePort> vPorts = new ArrayList<>();
        vPortStore.values().forEach(p -> {
            if (p.macAddress().equals(mac)) {
                vPorts.add(p);
            }
        });
        if (vPorts.size() == 0) {
            return null;
        }
        return vPorts.get(0);
    }

    @Override
    public BasePort getPort(TenantNetworkId networkId, IpAddress ip) {
        checkNotNull(networkId, NETWORKID_NOT_NULL);
        checkNotNull(ip, IP_NOT_NULL);
        List<BasePort> vPorts = new ArrayList<>();
        vPortStore.values().stream().filter(p -> p.networkId().equals(networkId))
                .forEach(p -> {
                    for (FixedIp fixedIp : p.fixedIps()) {
                        if (fixedIp.ip().equals(ip)) {
                            vPorts.add(p);
                            break;
                        }
                    }
                });
        if (vPorts.size() == 0) {
            return null;
        }
        return vPorts.get(0);
    }

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

    @Override
    public Collection<BasePort> getPorts(TenantNetworkId networkId) {
        checkNotNull(networkId, NETWORKID_NOT_NULL);
        return vPortStore.values().stream().filter(d -> d.networkId().equals(networkId))
                .collect(Collectors.toList());
    }

    @Override
    public Collection<BasePort> getPorts(TenantId tenantId) {
        checkNotNull(tenantId, TENANTID_NOT_NULL);
        return vPortStore.values().stream().filter(d -> d.tenantId().equals(tenantId))
                .collect(Collectors.toList());
    }

    @Override
    public Collection<BasePort> getPorts(DeviceId deviceId) {
        checkNotNull(deviceId, DEVICEID_NOT_NULL);
        return vPortStore.values().stream().filter(d -> d.deviceId().equals(deviceId))
                .collect(Collectors.toList());
    }

    @Override
    public boolean createPorts(Iterable<BasePort> vPorts) {
        checkNotNull(vPorts, BASEPORT_NOT_NULL);
        for (BasePort vPort : vPorts) {
            log.info("vPortId is  {} ", vPort.portId().toString());
            vPortStore.put(vPort.portId(), vPort);
            if (!vPortStore.containsKey(vPort.portId())) {
                log.info("The basePort is created failed whose identifier is" +
                                 " {} ",
                         vPort.portId().toString());
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean updatePorts(Iterable<BasePort> vPorts) {
        checkNotNull(vPorts, BASEPORT_NOT_NULL);
        for (BasePort vPort : vPorts) {
            vPortStore.put(vPort.portId(), vPort);
            if (!vPortStore.containsKey(vPort.portId())) {
                log.info("The basePort is not exist whose identifier is {}",
                         vPort.portId().toString());
                return false;
            }

            vPortStore.put(vPort.portId(), vPort);

            if (!vPort.equals(vPortStore.get(vPort.portId()))) {
                log.info("The basePort is updated failed whose  identifier " +
                                 "is {}",
                         vPort.portId().toString());
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean removePorts(Iterable<BasePortId> vPortIds) {
        checkNotNull(vPortIds, BASEPORT_ID_NULL);
        for (BasePortId vPortId : vPortIds) {
            vPortStore.remove(vPortId);
            if (vPortStore.containsKey(vPortId)) {
                log.info("The basePort is removed failed whose identifier is" +
                                 " {}",
                         vPortId.toString());
                return false;
            }
        }
        return true;
    }

    /**
     * Returns a collection of basePorts from subnetNodes.
     *
     * @param vPortNodes the basePort json node
     * @return BasePort collection of vpn ports
     */
    private Collection<BasePort> changeJsonToSub(JsonNode vPortNodes) {
        checkNotNull(vPortNodes, JSON_NOT_NULL);
        Set<FixedIp> fixedIps = null;
        TenantNetworkId tenantNetworkId = null;
        Map<BasePortId, BasePort> vportMap = new HashMap<>();
        Map<String, String> strMap = new HashMap<>();
        BasePortId basePortId = BasePortId.portId(vPortNodes.get("id").asText());
        String name = vPortNodes.get("name").asText();
        TenantId tenantId = TenantId
                .tenantId(vPortNodes.get("tenant_id").asText());
        Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
        String state = vPortNodes.get("status").asText();
        MacAddress macAddress = MacAddress
                .valueOf(vPortNodes.get("mac_address").asText());
        DeviceId deviceId = DeviceId
                .deviceId(vPortNodes.get("device_id").asText());
        String deviceOwner = vPortNodes.get("device_owner").asText();
        BindingHostId bindingHostId = BindingHostId
                .bindingHostId(vPortNodes.get("host_id").asText());
        String bindingVnicType = vPortNodes.get("vnic_type").asText();
        String bindingVifType = vPortNodes.get("vif_type").asText();
        String bindingVifDetails = vPortNodes.get("vif_details").asText();
        strMap.put("name", name);
        strMap.put("deviceOwner", deviceOwner);
        strMap.put("bindingVnicType", bindingVnicType);
        strMap.put("bindingVifType", bindingVifType);
        strMap.put("bindingVifDetails", bindingVifDetails);
        BasePort prevBasePort = getPort(basePortId);
        if (prevBasePort != null) {
            fixedIps = prevBasePort.fixedIps();
            tenantNetworkId = prevBasePort.networkId();
        }
        BasePort vPort = new DefaultBasePort(basePortId,
                                             tenantNetworkId,
                                             adminStateUp,
                                             strMap, state,
                                             macAddress, tenantId,
                                             deviceId, fixedIps,
                                             bindingHostId,
                                             null,
                                             null);
        vportMap.put(basePortId, vPort);

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

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

    }

    /**
     * process Etcd response for port information.
     *
     * @param action can be either update or delete
     * @param key    can contain the id and also target information
     * @param value  content of the port configuration
     */
    @Override
    public void processGluonConfig(String action, String key, JsonNode value) {
        Collection<BasePort> basePorts;
        switch (action) {
            case DELETE:
                String[] list = key.split(SLASH);
                BasePortId basePortId
                        = BasePortId.portId(list[list.length - 1]);
                Set<BasePortId> basePortIds = Sets.newHashSet(basePortId);
                removePorts(basePortIds);
                break;
            case SET:
                checkNotNull(value, RESPONSE_NOT_NULL);
                basePorts = changeJsonToSub(value);
                createPorts(basePorts);
                break;
            case UPDATE:
                checkNotNull(value, RESPONSE_NOT_NULL);
                basePorts = changeJsonToSub(value);
                updatePorts(basePorts);
                break;
            default:
                log.info("Invalid action is received while processing VPN " +
                                 "port configuration");
        }
    }

    private void parseEtcdResponse(JsonNode jsonNode,
                                   String key,
                                   String action) {
        JsonNode modifyValue = null;
        if (action.equals(SET)) {
            modifyValue = jsonNode.get(key);
        }
        String[] list = key.split(SLASH);
        String target = list[list.length - 2];
        if (target.equals(PROTON_BASE_PORT)) {
            processGluonConfig(action, key, modifyValue);
        }
    }

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

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

    /**
     * Notifies specify event to all listeners.
     *
     * @param event vpn af config event
     */
    private void notifyListeners(BasePortEvent event) {
        checkNotNull(event, EVENT_NOT_NULL);
        listeners.forEach(listener -> listener.event(event));
    }
}
