/*
 * Copyright 2017-present Open Networking Laboratory
 *
 * 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.opencord.cordvtn.cli;

import com.google.common.base.Strings;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.cli.AbstractShellCommand;
import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
import org.opencord.cordvtn.api.net.NetworkId;
import org.opencord.cordvtn.api.net.PortId;
import org.opencord.cordvtn.api.net.SegmentId;
import org.opencord.cordvtn.api.net.ServiceNetwork;
import org.opencord.cordvtn.api.net.ServicePort;
import org.opencord.cordvtn.impl.DefaultServiceNetwork;
import org.opencord.cordvtn.impl.DefaultServicePort;
import org.openstack4j.api.OSClient;
import org.openstack4j.api.exceptions.AuthenticationException;
import org.openstack4j.model.identity.Access;
import org.openstack4j.openstack.OSFactory;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Synchronizes network states with OpenStack Neutron.
 * This command can be used to actively synchronize Neutron network with VTN
 * service network.
 */
@Command(scope = "onos", name = "cordvtn-sync-neutron-states",
        description = "Synchronizes network states with Neutron")
public class CordVtnSyncNeutronStatesCommand extends AbstractShellCommand {

    @Argument(index = 0, name = "endpoint", description = "OpenStack service endpoint",
            required = true, multiValued = false)
    private String endpoint = null;

    @Argument(index = 1, name = "tenant", description = "OpenStack admin tenant name",
            required = true, multiValued = false)
    private String tenant = null;

    @Argument(index = 2, name = "user", description = "OpenStack admin user name",
            required = true, multiValued = false)
    private String user = null;

    @Argument(index = 3, name = "password", description = "OpenStack admin user password",
            required = true, multiValued = false)
    private String password = null;

    private static final String NET_FORMAT = "%-40s%-20s%-20s%-8s%-20s%s";
    private static final String PORT_FORMAT = "%-40s%-20s%-18s%-8s%s";

    @Override
    protected void execute() {
        ServiceNetworkAdminService snetService =
                AbstractShellCommand.get(ServiceNetworkAdminService.class);
        Access osAccess;
        try {
            osAccess = OSFactory.builder()
                    .endpoint(this.endpoint)
                    .tenantName(this.tenant)
                    .credentials(this.user, this.password)
                    .authenticate()
                    .getAccess();
        } catch (AuthenticationException e) {
            print("Authentication failed");
            return;
        } catch (Exception e) {
            print("OpenStack service endpoint is unreachable");
            return;
        }

        print("Synchronizing service networks...");
        print(NET_FORMAT, "ID", "Name", "Type", "VNI", "Subnet", "Service IP");
        OSClient osClient = OSFactory.clientFromAccess(osAccess);
        osClient.networking().network().list().forEach(osNet -> {
            ServiceNetwork snet = DefaultServiceNetwork.builder()
                    .id(NetworkId.of(osNet.getId()))
                    .name(osNet.getName())
                    .type(ServiceNetwork.NetworkType.PRIVATE)
                    .segmentId(SegmentId.of(Long.valueOf(osNet.getProviderSegID())))
                    .build();
            try {
                if (snetService.serviceNetwork(snet.id()) != null) {
                    snetService.updateServiceNetwork(snet);
                } else {
                    snetService.createServiceNetwork(snet);
                }
            } catch (Exception ignore) {
            }
        });

        osClient.networking().subnet().list().forEach(osSubnet -> {
            try {
                ServiceNetwork snet = DefaultServiceNetwork.builder()
                        .id(NetworkId.of(osSubnet.getNetworkId()))
                        .subnet(IpPrefix.valueOf(osSubnet.getCidr()))
                        .serviceIp(IpAddress.valueOf(osSubnet.getGateway()))
                        .build();
                snetService.updateServiceNetwork(snet);
                ServiceNetwork updated = snetService.serviceNetwork(snet.id());
                print(NET_FORMAT, updated.id(),
                      updated.name(),
                      updated.type(),
                      updated.segmentId(),
                      updated.subnet(),
                      updated.serviceIp());
            } catch (Exception e) {
                print(e.getMessage());
            }
        });

        print("\nSynchronizing service ports...");
        print(PORT_FORMAT, "ID", "MAC", "IP", "VLAN", "WAN IPs");
        osClient.networking().port().list().forEach(osPort -> {
            ServicePort.Builder sportBuilder = DefaultServicePort.builder()
                    .id(PortId.of(osPort.getId()))
                    .networkId(NetworkId.of(osPort.getNetworkId()));

            if (!Strings.isNullOrEmpty(osPort.getName())) {
                sportBuilder.name(osPort.getName());
            }
            if (osPort.getMacAddress() != null) {
                sportBuilder.mac(MacAddress.valueOf(osPort.getMacAddress()));
            }
            if (!osPort.getFixedIps().isEmpty()) {
                sportBuilder.ip(IpAddress.valueOf(
                        osPort.getFixedIps().iterator().next().getIpAddress()));
            }
            ServicePort sport = sportBuilder.build();
            if (snetService.servicePort(sport.id()) != null) {
                snetService.updateServicePort(sport);
            } else {
                snetService.createServicePort(sport);
            }
            ServicePort updated = snetService.servicePort(sport.id());
            List<String> floatingIps = updated.addressPairs().stream()
                    .map(ip -> ip.ip().toString())
                    .collect(Collectors.toList());
            print(PORT_FORMAT, updated.id(),
                  updated.mac(),
                  updated.ip(),
                  updated.vlanId() != null ? updated.vlanId() : "",
                  floatingIps.isEmpty() ? "" : floatingIps);
        });
    }
}
