package net.onrc.onos.apps.bgproute;

import java.util.Iterator;

import net.onrc.onos.apps.bgproute.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;

public class BgpRouteResource extends ServerResource {

    protected final static Logger log = LoggerFactory.getLogger(BgpRouteResource.class);

    @Get
    public String get(String fmJson) {
        String dest = (String) getRequestAttributes().get("dest");
        String output = "";
        IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
                get(IBgpRouteService.class.getCanonicalName());

        if (dest != null) {
            //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 = bgpRoute.getBGPdRestIp();
            String url = "http://" + BGPdRestIp + "/wm/bgp/" + dest;

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

            output = "Get rib from bgpd finished!\n";
            return output;
        } else {
            IPatriciaTrie<RibEntry> ptree = bgpRoute.getPtree();
            output += "{\n  \"rib\": [\n";
            boolean printed = false;

            synchronized (ptree) {
                Iterator<IPatriciaTrie.Entry<RibEntry>> it = ptree.iterator();
                while (it.hasNext()) {
                    IPatriciaTrie.Entry<RibEntry> entry = it.next();

                    if (printed == true) {
                        output += ",\n";
                    }

                    output += "    {\"prefix\": \"" + entry.getPrefix() + "\", ";
                    output += "\"nexthop\": \"" + entry.getValue().getNextHop().getHostAddress() + "\"}";

                    printed = true;
                }
            }

            output += "\n  ]\n}\n";
        }

        return output;
    }

    @Post
    public String store(String fmJson) {
        IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
                get(IBgpRouteService.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.valueOf(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);

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

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

        return reply + "\n";
    }

    @Delete
    public String delete(String fmJson) {
        IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
                get(IBgpRouteService.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 delete
            Prefix p;
            long sysUpTime, sequenceNum;
            try {
                p = new Prefix(prefix, Integer.valueOf(mask));
                sysUpTime = Long.parseLong(strSysuptime);
                sequenceNum = Long.parseLong(strSequence);
            } catch (NumberFormatException e) {
                reply = "[DELE: mask format is wrong]";
                log.info(reply);
                return reply + "\n";
            } catch (IllegalArgumentException e1) {
                reply = "[DELE: prefix format is wrong]";
                log.info(reply);
                return reply + "\n";
            }

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

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

            reply = reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "]";
        } else {
            // clear the local rib: Ptree
            bgpRoute.clearPtree();
            reply = "[DELE-capability: " + capability + "; The local RibEntry is cleared!]\n";

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

        log.info(reply);
        return reply + "\n";
    }
}
