/*
 * Copyright 2015 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.onosproject.vtnweb.resources;

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.OK;

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 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 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.vtnrsc.web.VirtualPortCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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;

/**
 * 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 })
    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 })
    public Response getportsById(@PathParam("id") String id) {

        if (!get(VirtualPortService.class).exists(VirtualPortId.portId(id))) {
            return ok("The virtualPort does not exists").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();
        }
    }

    @Path("{portUUID}")
    @DELETE
    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 Response.status(OK).entity(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 (state.equals("ACTIVE")) {
            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;
    }
}
