package net.onrc.onos.apps.sdnip.web;

import java.util.Iterator;

import net.onrc.onos.apps.sdnip.ISdnIpService;
import net.onrc.onos.apps.sdnip.Prefix;
import net.onrc.onos.apps.sdnip.RestClient;
import net.onrc.onos.apps.sdnip.RibEntry;
import net.onrc.onos.apps.sdnip.RibUpdate;
import net.onrc.onos.apps.sdnip.RibUpdate.Operation;

import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.concurrenttrees.common.KeyValuePair;
import com.googlecode.concurrenttrees.radix.RadixTree;

/**
 * REST resource that handles REST calls from BGPd. This is the interface BGPd
 * uses to push RIB entries (routes) to SDN-IP.
 */
public class IncomingRequestResource extends ServerResource {
    private static final Logger log = LoggerFactory.getLogger(IncomingRequestResource.class);

    /**
     * Gets the contents of SDN-IP's route table.
     *
     * @return the contents of SDN-IP's route table formatted as JSON
     */
    @Get
    public String handleGetMethod() {
        String dest = (String) getRequestAttributes().get("dest");
        StringBuilder output = new StringBuilder(80);
        ISdnIpService sdnIp = (ISdnIpService) getContext()
                .getAttributes().
                get(ISdnIpService.class.getCanonicalName());

        if (dest == null) {
            RadixTree<RibEntry> radixTree = sdnIp.getPtree();
            output.append("{\n  \"rib\": [\n");
            boolean printed = false;

            Iterator<KeyValuePair<RibEntry>> it =
                    radixTree.getKeyValuePairsForKeysStartingWith("").iterator();
            while (it.hasNext()) {
                KeyValuePair<RibEntry> entry = it.next();

                if (printed) {
                    output.append(",\n");
                }

                output.append("    {\"prefix\": \"");
                output.append(Prefix.fromBinaryString(entry.getKey().toString()));
                output.append("\", \"nexthop\": \"");
                output.append(entry.getValue().getNextHop().getHostAddress());
                output.append("\"}");

                printed = true;
            }

            output.append("\n  ]\n}\n");
        } else {
            // TODO Needs to be changed to use the new RestClient.get().

            // the dest here refers to router-id
            // bgpdRestIp includes port number, such as 1.1.1.1:8080
            String bgpdRestIp = sdnIp.getBgpdRestIp();
            String url = "http://" + bgpdRestIp + "/wm/bgp/" + dest;

            // Doesn't actually do anything with the response
            RestClient.get(url);

            output.append("Get rib from bgpd finished!\n");
        }

        return output.toString();
    }

    /**
     * Handler to receive a new RIB entry. The details of the RIB entry are
     * given as part of the URL.
     *
     * @return a String describing the result of the action
     */
    @Post
    public String handlePostMethod() {
        ISdnIpService sdnIp = (ISdnIpService) getContext()
                .getAttributes().
                get(ISdnIpService.class.getCanonicalName());

        String strSysuptime = (String) getRequestAttributes().get("sysuptime");
        String strSequence = (String) getRequestAttributes().get("sequence");
        String routerId = (String) getRequestAttributes().get("routerid");
        String prefix = (String) getRequestAttributes().get("prefix");
        String mask = (String) getRequestAttributes().get("mask");
        String nexthop = (String) getRequestAttributes().get("nexthop");
        String capability = (String) getRequestAttributes().get("capability");

        log.debug("sysuptime: {}", strSysuptime);
        log.debug("sequence: {}", strSequence);

        String reply = "";

        if (capability == null) {
            // this is a prefix add
            Prefix p;
            long sysUpTime, sequenceNum;
            try {
                p = new Prefix(prefix, Integer.parseInt(mask));
                sysUpTime = Long.parseLong(strSysuptime);
                sequenceNum = Long.parseLong(strSequence);
            } catch (NumberFormatException e) {
                reply = "[POST: mask format is wrong]";
                log.info(reply);
                return reply + "\n";
            } catch (IllegalArgumentException e1) {
                reply = "[POST: prefix format is wrong]";
                log.info(reply);
                return reply + "\n";
            }

            RibEntry rib = new RibEntry(routerId, nexthop, sysUpTime,
                    sequenceNum);

            sdnIp.newRibUpdate(new RibUpdate(Operation.UPDATE, p, rib));

            reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "]";
            log.info(reply);
        } else {
            reply = "[POST-capability: " + capability + "]\n";
            log.info(reply);
            // to store the number in the top node of the Ptree
        }
        /*else if ("1".equals(capability)) {
            reply = "[POST-capability: " + capability + "]\n";
            log.info(reply);
            // to store the number in the top node of the Ptree
        }*/

        return reply + "\n";
    }

    /**
     * Handler to remove a RIB entry from ONOS's route table. The details of
     * the route to remove are passed as part of the URL.
     *
     * @return a String describing the result of the action
     */
    @Delete
    public String handleDeleteMethod() {
        ISdnIpService sdnIp = (ISdnIpService) getContext()
                .getAttributes().
                get(ISdnIpService.class.getCanonicalName());

        String strSysuptime = (String) getRequestAttributes().get("sysuptime");
        String strSequence = (String) getRequestAttributes().get("sequence");
        String routerId = (String) getRequestAttributes().get("routerid");
        String prefix = (String) getRequestAttributes().get("prefix");
        String mask = (String) getRequestAttributes().get("mask");
        String nextHop = (String) getRequestAttributes().get("nexthop");
        String capability = (String) getRequestAttributes().get("capability");

        log.debug("sysuptime: {}", strSysuptime);
        log.debug("sequence: {}", strSequence);

        //String reply = "";
        StringBuilder replyStringBuilder = new StringBuilder(80);

        if (capability == null) {
            // this is a prefix delete
            Prefix p;
            long sysUpTime, sequenceNum;
            try {
                p = new Prefix(prefix, Integer.parseInt(mask));
                sysUpTime = Long.parseLong(strSysuptime);
                sequenceNum = Long.parseLong(strSequence);
            } catch (NumberFormatException e) {
                String reply = "[DELE: mask format is wrong]";
                log.info(reply);
                return reply + "\n";
            } catch (IllegalArgumentException e1) {
                String reply = "[DELE: prefix format is wrong]";
                log.info(reply);
                return reply + "\n";
            }

            RibEntry r = new RibEntry(routerId, nextHop, sysUpTime, sequenceNum);

            sdnIp.newRibUpdate(new RibUpdate(Operation.DELETE, p, r));

            replyStringBuilder.append("[DELE: ")
                .append(prefix)
                .append('/')
                .append(mask)
                .append(':')
                .append(nextHop)
                .append(']');
        } else {
            // clear the local rib: Ptree
            sdnIp.clearPtree();
            replyStringBuilder.append("[DELE-capability: ")
                    .append(capability)
                    .append("; The local RibEntry is cleared!]\n");

            // to store the number in the top node of the Ptree
        }

        log.info(replyStringBuilder.toString());
        replyStringBuilder.append('\n');
        return replyStringBuilder.toString();
    }
}
