/*
 * 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.vtnweb.resources;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.net.DeviceId;
import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultVirtualPort;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.SecurityGroup;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPort.State;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.onosproject.vtnweb.web.VirtualPortCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
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 java.util.concurrent.ConcurrentMap;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;

/**
 * REST resource for interacting with the inventory of infrastructure
 * virtualPort.
 */
@Path("ports")
public class VirtualPortWebResource extends AbstractWebResource {
    public static final String VPORT_NOT_FOUND = "VirtualPort is not found";
    public static final String VPORT_ID_EXIST = "VirtualPort id is exist";
    public static final String VPORT_ID_NOT_EXIST = "VirtualPort id is not exist";
    public static final String JSON_NOT_NULL = "JsonNode can not be null";
    protected static final Logger log = LoggerFactory
            .getLogger(VirtualPortService.class);

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response getPorts() {
        Iterable<VirtualPort> virtualPorts = get(VirtualPortService.class)
                .getPorts();
        ObjectNode result = new ObjectMapper().createObjectNode();
        result.set("ports", new VirtualPortCodec().encode(virtualPorts, this));
        return ok(result.toString()).build();
    }

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response getportsById(@PathParam("id") String id) {

        if (!get(VirtualPortService.class).exists(VirtualPortId.portId(id))) {
            return Response.status(NOT_FOUND)
                    .entity(VPORT_NOT_FOUND).build();
        }
        VirtualPort virtualPort = nullIsNotFound(get(VirtualPortService.class)
                .getPort(VirtualPortId.portId(id)), VPORT_NOT_FOUND);
        ObjectNode result = new ObjectMapper().createObjectNode();
        result.set("port", new VirtualPortCodec().encode(virtualPort, this));
        return ok(result.toString()).build();
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createPorts(InputStream input) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode cfg = mapper.readTree(input);
            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
                    .createPorts(vPorts), VPORT_NOT_FOUND);
            if (!issuccess) {
                return Response.status(INTERNAL_SERVER_ERROR)
                        .entity(VPORT_ID_NOT_EXIST).build();
            }
            return Response.status(OK).entity(issuccess.toString()).build();
        } catch (Exception e) {
            log.error("Creates VirtualPort failed because of exception {}",
                      e.toString());
            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
                    .build();
        }
    }

    @DELETE
    @Path("{portUUID}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response deletePorts(@PathParam("portUUID") String id) {
        Set<VirtualPortId> vPortIds = new HashSet<>();
        try {
            if (id != null) {
                vPortIds.add(VirtualPortId.portId(id));
            }
            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
                    .removePorts(vPortIds), VPORT_NOT_FOUND);
            if (!issuccess) {
                return Response.status(INTERNAL_SERVER_ERROR)
                        .entity(VPORT_ID_NOT_EXIST).build();
            }
            return ok(issuccess.toString()).build();
        } catch (Exception e) {
            log.error("Deletes VirtualPort failed because of exception {}",
                      e.toString());
            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
                    .build();
        }
    }

    @PUT
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response updatePorts(@PathParam("id") String id, InputStream input) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode cfg = mapper.readTree(input);
            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
                    .updatePorts(vPorts), VPORT_NOT_FOUND);
            if (!issuccess) {
                return Response.status(INTERNAL_SERVER_ERROR)
                        .entity(VPORT_ID_NOT_EXIST).build();
            }
            return Response.status(OK).entity(issuccess.toString()).build();
        } catch (Exception e) {
            log.error("Updates failed because of exception {}", e.toString());
            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
                    .build();
        }
    }

    /**
     * Returns a Object of the currently known infrastructure virtualPort.
     *
     * @param vPortNode the virtualPort json node
     * @return a collection of virtualPorts
     */
    public Iterable<VirtualPort> createOrUpdateByInputStream(JsonNode vPortNode) {
        checkNotNull(vPortNode, JSON_NOT_NULL);
        JsonNode vPortNodes = vPortNode.get("ports");
        if (vPortNodes == null) {
            vPortNodes = vPortNode.get("port");
        }
        if (vPortNodes.isArray()) {
            return changeJsonToPorts(vPortNodes);
        } else {
            return changeJsonToPort(vPortNodes);
        }
    }

    /**
     * Returns the iterable collection of virtualports from subnetNodes.
     *
     * @param vPortNodes the virtualPort json node
     * @return virtualPorts a collection of virtualPorts
     */
    public Iterable<VirtualPort> changeJsonToPorts(JsonNode vPortNodes) {
        checkNotNull(vPortNodes, JSON_NOT_NULL);
        Map<VirtualPortId, VirtualPort> portMap = new HashMap<>();
        Map<String, String> strMap = new HashMap<>();
        for (JsonNode vPortnode : vPortNodes) {
            VirtualPortId id = VirtualPortId.portId(vPortnode.get("id")
                    .asText());
            String name = vPortnode.get("name").asText();
            TenantId tenantId = TenantId.tenantId(vPortnode.get("tenant_id")
                    .asText());
            TenantNetworkId networkId = TenantNetworkId.networkId(vPortnode
                    .get("network_id").asText());
            checkArgument(vPortnode.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
            Boolean adminStateUp = vPortnode.get("admin_state_up").asBoolean();
            String state = vPortnode.get("status").asText();
            MacAddress macAddress = MacAddress.valueOf(vPortnode
                    .get("mac_address").asText());
            DeviceId deviceId = DeviceId.deviceId(vPortnode.get("device_id")
                    .asText());
            String deviceOwner = vPortnode.get("device_owner").asText();
            JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
            Set<FixedIp> fixedIps = new HashSet<>();
            for (JsonNode fixedIpNode : fixedIpNodes) {
                FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
                fixedIps.add(fixedIp);
            }

            BindingHostId bindingHostId = BindingHostId
                    .bindingHostId(vPortnode.get("binding:host_id").asText());
            String bindingVnicType = vPortnode.get("binding:vnic_type")
                    .asText();
            String bindingVifType = vPortnode.get("binding:vif_type").asText();
            String bindingVifDetails = vPortnode.get("binding:vif_details")
                    .asText();
            JsonNode allowedAddressPairJsonNode = vPortnode
                    .get("allowed_address_pairs");
            Collection<AllowedAddressPair> allowedAddressPairs =
                    jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
            JsonNode securityGroupNode = vPortnode.get("security_groups");
            Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
            strMap.put("name", name);
            strMap.put("deviceOwner", deviceOwner);
            strMap.put("bindingVnicType", bindingVnicType);
            strMap.put("bindingVifType", bindingVifType);
            strMap.put("bindingVifDetails", bindingVifDetails);
            VirtualPort vPort = new DefaultVirtualPort(id, networkId,
                                                       adminStateUp, strMap,
                                                       isState(state),
                                                       macAddress, tenantId,
                                                       deviceId, fixedIps,
                                                       bindingHostId,
                                                       Sets.newHashSet(allowedAddressPairs),
                                                       Sets.newHashSet(securityGroups));
            portMap.put(id, vPort);
        }
        return Collections.unmodifiableCollection(portMap.values());
    }

    /**
     * Returns a collection of virtualPorts from subnetNodes.
     *
     * @param vPortNodes the virtualPort json node
     * @return virtualPorts a collection of virtualPorts
     */
    public Iterable<VirtualPort> changeJsonToPort(JsonNode vPortNodes) {
        checkNotNull(vPortNodes, JSON_NOT_NULL);
        Map<VirtualPortId, VirtualPort> vportMap = new HashMap<>();
        Map<String, String> strMap = new HashMap<>();
        VirtualPortId id = VirtualPortId.portId(vPortNodes.get("id").asText());
        String name = vPortNodes.get("name").asText();
        TenantId tenantId = TenantId.tenantId(vPortNodes.get("tenant_id")
                .asText());
        TenantNetworkId networkId = TenantNetworkId.networkId(vPortNodes
                .get("network_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();
        JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
        Set<FixedIp> fixedIps = new HashSet<>();
        for (JsonNode fixedIpNode : fixedIpNodes) {
            FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
            fixedIps.add(fixedIp);
        }

        BindingHostId bindingHostId = BindingHostId
                .bindingHostId(vPortNodes.get("binding:host_id").asText());
        String bindingVnicType = vPortNodes.get("binding:vnic_type").asText();
        String bindingVifType = vPortNodes.get("binding:vif_type").asText();
        String bindingVifDetails = vPortNodes.get("binding:vif_details")
                .asText();
        JsonNode allowedAddressPairJsonNode = vPortNodes
                .get("allowed_address_pairs");
        Collection<AllowedAddressPair> allowedAddressPairs =
                jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
        JsonNode securityGroupNode = vPortNodes.get("security_groups");
        Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
        strMap.put("name", name);
        strMap.put("deviceOwner", deviceOwner);
        strMap.put("bindingVnicType", bindingVnicType);
        strMap.put("bindingVifType", bindingVifType);
        strMap.put("bindingVifDetails", bindingVifDetails);
        VirtualPort vPort = new DefaultVirtualPort(id, networkId, adminStateUp,
                                                   strMap, isState(state),
                                                   macAddress, tenantId,
                                                   deviceId, fixedIps,
                                                   bindingHostId,
                                                   Sets.newHashSet(allowedAddressPairs),
                                                   Sets.newHashSet(securityGroups));
        vportMap.put(id, vPort);

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

    /**
     * Returns a Object of the currently known infrastructure virtualPort.
     *
     * @param allowedAddressPairs the allowedAddressPairs json node
     * @return a collection of allowedAddressPair
     */
    public Collection<AllowedAddressPair> jsonNodeToAllowedAddressPair(JsonNode allowedAddressPairs) {
        checkNotNull(allowedAddressPairs, JSON_NOT_NULL);
        ConcurrentMap<Integer, AllowedAddressPair> allowMaps = Maps
                .newConcurrentMap();
        int i = 0;
        for (JsonNode node : allowedAddressPairs) {
            IpAddress ip = IpAddress.valueOf(node.get("ip_address").asText());
            MacAddress mac = MacAddress.valueOf(node.get("mac_address")
                    .asText());
            AllowedAddressPair allows = AllowedAddressPair
                    .allowedAddressPair(ip, mac);
            allowMaps.put(i, allows);
            i++;
        }
        log.debug("The jsonNode of allowedAddressPairallow is {}"
                + allowedAddressPairs.toString());
        return Collections.unmodifiableCollection(allowMaps.values());
    }

    /**
     * Returns a collection of virtualPorts.
     *
     * @param securityGroups the virtualPort jsonnode
     * @return a collection of securityGroups
     */
    public Collection<SecurityGroup> jsonNodeToSecurityGroup(JsonNode securityGroups) {
        checkNotNull(securityGroups, JSON_NOT_NULL);
        ConcurrentMap<Integer, SecurityGroup> securMaps = Maps
                .newConcurrentMap();
        int i = 0;
        for (JsonNode node : securityGroups) {
            SecurityGroup securityGroup = SecurityGroup
                    .securityGroup(node.asText());
            securMaps.put(i, securityGroup);
            i++;
        }
        return Collections.unmodifiableCollection(securMaps.values());
    }

    /**
     * Returns a collection of fixedIps.
     *
     * @param fixedIpNode the fixedIp jsonnode
     * @return a collection of SecurityGroup
     */
    public FixedIp jsonNodeToFixedIps(JsonNode fixedIpNode) {
        SubnetId subnetId = SubnetId.subnetId(fixedIpNode.get("subnet_id")
                .asText());
        IpAddress ipAddress = IpAddress.valueOf(fixedIpNode.get("ip_address")
                .asText());
        FixedIp fixedIps = FixedIp.fixedIp(subnetId, ipAddress);
        return fixedIps;
    }

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

    }

    /**
     * Returns the specified item if that items is null; otherwise throws not
     * found exception.
     *
     * @param item item to check
     * @param <T> item type
     * @param message not found message
     * @return item if not null
     * @throws org.onlab.util.ItemNotFoundException if item is null
     */
    protected <T> T nullIsNotFound(T item, String message) {
        if (item == null) {
            throw new ItemNotFoundException(message);
        }
        return item;
    }
}
