/*
 * 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.vtnrsc.cli.virtualport;

import java.util.Map;
import java.util.Set;

import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Option;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.DeviceId;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultVirtualPort;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.Subnet;
import org.onosproject.vtnrsc.TenantNetwork;
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 com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * Supports for updating the external gateway virtualPort.
 */
@Service
@Command(scope = "onos", name = "externalgateway-update",
        description = "Supports for updating the external gateway virtualPort.")
public class VirtualPortExGwUpdateCommand extends AbstractShellCommand {

    @Option(name = "-m", aliases = "--macAddress", description = "MAC address.", required = true,
            multiValued = false)
    String macAddress = "";

    @Override
    protected void doExecute() {
        VirtualPortService service = get(VirtualPortService.class);
        SubnetService subnetService = get(SubnetService.class);
        TenantNetworkService tenantNetworkService = get(TenantNetworkService.class);
        Iterable<TenantNetwork> networks = tenantNetworkService.getNetworks();
        if (networks != null) {
            for (TenantNetwork network : networks) {
                if (network.routerExternal()) {
                    Iterable<Subnet> subnets = subnetService.getSubnets();
                    if (subnets != null) {
                        for (Subnet subnet : subnets) {
                            if (network.id().networkId().equals(subnet.networkId().networkId())) {
                                IpAddress exgwip = subnet.gatewayIp();
                                FixedIp fixedGwIp = FixedIp.fixedIp(subnet.id(), exgwip);
                                VirtualPort exgwPort = service.getPort(fixedGwIp);
                                if (exgwPort == null) {
                                    createExGwPort(network, subnet, fixedGwIp);
                                } else {
                                    updateExGwPort(exgwPort);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void createExGwPort(TenantNetwork network, Subnet subnet, FixedIp fixedGwIp) {
        VirtualPortService service = get(VirtualPortService.class);
        Map<String, String> strMap = Maps.newHashMap();
        VirtualPort virtualPort = new DefaultVirtualPort(VirtualPortId.portId("externalgateway-update-id"),
                                                         network.id(),
                                                         false, strMap,
                                                         VirtualPort.State.DOWN,
                                                         MacAddress.valueOf(macAddress),
                                                         subnet.tenantId(),
                                                         DeviceId.deviceId(""),
                                                         Sets.newHashSet(fixedGwIp),
                                                         BindingHostId.bindingHostId(""),
                                                         Sets.newHashSet(),
                                                         Sets.newHashSet());
        Set<VirtualPort> virtualPorts = Sets.newHashSet(virtualPort);
        service.createPorts(virtualPorts);
    }

    private void updateExGwPort(VirtualPort exgwPort) {
        VirtualPortService service = get(VirtualPortService.class);
        Map<String, String> strMap = Maps.newHashMap();
        strMap.putIfAbsent("name", exgwPort.name());
        strMap.putIfAbsent("deviceOwner", exgwPort.deviceOwner());
        strMap.putIfAbsent("bindingvnicType", exgwPort.bindingVnicType());
        strMap.putIfAbsent("bindingvifType", exgwPort.bindingVifType());
        strMap.putIfAbsent("bindingvnicDetails", exgwPort.bindingVifDetails());
        VirtualPort virtualPort = new DefaultVirtualPort(exgwPort.portId(),
                                                         exgwPort.networkId(),
                                                         false, strMap,
                                                         VirtualPort.State.DOWN,
                                                         MacAddress.valueOf(macAddress),
                                                         exgwPort.tenantId(),
                                                         exgwPort.deviceId(),
                                                         exgwPort.fixedIps(),
                                                         exgwPort.bindingHostId(),
                                                         Sets.newHashSet(exgwPort
                                                                .allowedAddressPairs()),
                                                         Sets.newHashSet(exgwPort
                                                                .securityGroups()));
        Set<VirtualPort> virtualPorts = Sets.newHashSet(virtualPort);
        service.updatePorts(virtualPorts);
    }
}
