/*
 * 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.VirtualPortId;
import org.onosproject.vtnrsc.VirtualPort.State;
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;

/**
 * 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<VirtualPortId>();
        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<VirtualPortId, VirtualPort>();
        Map<String, String> strMap = new HashMap<String, String>();
        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<FixedIp>();
            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,
                                                       allowedAddressPairs,
                                                       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<VirtualPortId, VirtualPort>();
        Map<String, String> strMap = new HashMap<String, String>();
        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<FixedIp>();
        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,
                                                   allowedAddressPairs,
                                                   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;
    }
}
