package net.floodlightcontroller.firewall;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.MappingJsonFactory;
import org.openflow.util.HexString;
import org.restlet.resource.Delete;
import org.restlet.resource.Post;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;

public class FirewallRulesResource extends ServerResource {
    protected static Logger log = LoggerFactory.getLogger(FirewallRulesResource.class);

    @Get("json")
    public Object handleRequest() {
        IFirewallService firewall = 
                (IFirewallService)getContext().getAttributes().
                get(IFirewallService.class.getCanonicalName());

        return firewall.getRules();
    }

    /**
     * Takes a Firewall Rule string in JSON format and parses it into
     * our firewall rule data structure, then adds it to the firewall.
     * @param fmJson The Firewall rule entry in JSON format.
     * @return A string status message
     */
    @Post
    public String store(String fmJson) {
        IFirewallService firewall = 
                (IFirewallService)getContext().getAttributes().
                get(IFirewallService.class.getCanonicalName());

        FirewallRule rule;
        try {
            rule = jsonToFirewallRule(fmJson);
        } catch (IOException e) {
            log.error("Error parsing firewall rule: " + fmJson, e);
            e.printStackTrace();
            return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
        }
        String status = null;
        if (checkRuleExists(rule, firewall.getRules())) {
            status = "Error! A similar firewall rule already exists.";
            log.error(status);
        } else {
            // add rule to firewall
            firewall.addRule(rule);
            status = "Rule added";
        }
        return ("{\"status\" : \"" + status + "\"}");
    }

    /**
     * Takes a Firewall Rule string in JSON format and parses it into
     * our firewall rule data structure, then deletes it from the firewall.
     * @param fmJson The Firewall rule entry in JSON format.
     * @return A string status message
     */
    
    @Delete
    public String remove(String fmJson) {
        IFirewallService firewall = 
                (IFirewallService)getContext().getAttributes().
                get(IFirewallService.class.getCanonicalName());

        FirewallRule rule;
        try {
            rule = jsonToFirewallRule(fmJson);
        } catch (IOException e) {
            log.error("Error parsing firewall rule: " + fmJson, e);
            e.printStackTrace();
            return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
        }
        String status = null;
        boolean exists = false;
        Iterator<FirewallRule> iter = firewall.getRules().iterator();
        while (iter.hasNext()) {
            FirewallRule r = iter.next();
            if (r.ruleid == rule.ruleid) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            status = "Error! Can't delete, a rule with this ID doesn't exist.";
            log.error(status);
        } else {
            // delete rule from firewall
            firewall.deleteRule(rule.ruleid);
            status = "Rule deleted";
        }
        return ("{\"status\" : \"" + status + "\"}");
    }

    /**
     * Turns a JSON formatted Firewall Rule string into a FirewallRule instance
     * @param fmJson The JSON formatted static firewall rule
     * @return The FirewallRule instance
     * @throws IOException If there was an error parsing the JSON
     */
     
    public static FirewallRule jsonToFirewallRule(String fmJson) throws IOException {
        FirewallRule rule = new FirewallRule();
        MappingJsonFactory f = new MappingJsonFactory();
        JsonParser jp;

        try {
            jp = f.createJsonParser(fmJson);
        } catch (JsonParseException e) {
            throw new IOException(e);
        }

        jp.nextToken();
        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
            throw new IOException("Expected START_OBJECT");
        }

        while (jp.nextToken() != JsonToken.END_OBJECT) {
            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
                throw new IOException("Expected FIELD_NAME");
            }

            String n = jp.getCurrentName();
            jp.nextToken();
            if (jp.getText().equals("")) 
                continue;

            String tmp;
            
            // This is currently only applicable for remove().  In store(), ruleid takes a random number
            if (n == "ruleid") {
                rule.ruleid = Integer.parseInt((String)jp.getText());
            }
            
            // This assumes user having dpid info for involved switches
            else if (n == "switchid") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("-1") == false) {
                    // user inputs hex format dpid 
                    rule.dpid = HexString.toLong(tmp);                    
                    rule.wildcard_dpid = false;
                }
            } 
            
            else if (n == "src-inport") {
                rule.in_port = Short.parseShort(jp.getText());
                rule.wildcard_in_port = false;
            } 
            
            else if (n == "src-mac") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ANY") == false) {
                    rule.wildcard_dl_src = false;
                    rule.dl_src = Ethernet.toLong(Ethernet.toMACAddress(tmp));
                }
            } 
            
            else if (n == "dst-mac") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ANY") == false) {
                    rule.wildcard_dl_dst = false;
                    rule.dl_dst = Ethernet.toLong(Ethernet.toMACAddress(tmp));
                }
            } 
            
            else if (n == "dl-type") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ARP")) {
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_ARP;
                }
            } 
            
            else if (n == "src-ip") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ANY") == false) {
                    rule.wildcard_nw_src = false;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                    int[] cidr = IPCIDRToPrefixBits(tmp);
                    rule.nw_src_prefix = cidr[0];
                    rule.nw_src_maskbits = cidr[1];
                }
            } 
            
            else if (n == "dst-ip") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ANY") == false) {
                    rule.wildcard_nw_dst = false;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                    int[] cidr = IPCIDRToPrefixBits(tmp);
                    rule.nw_dst_prefix = cidr[0];
                    rule.nw_dst_maskbits = cidr[1];
                }
            } 
            
            else if (n == "nw-proto") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("TCP")) {
                    rule.wildcard_nw_proto = false;
                    rule.nw_proto = IPv4.PROTOCOL_TCP;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                } else if (tmp.equalsIgnoreCase("UDP")) {
                    rule.wildcard_nw_proto = false;
                    rule.nw_proto = IPv4.PROTOCOL_UDP;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                } else if (tmp.equalsIgnoreCase("ICMP")) {
                    rule.wildcard_nw_proto = false;
                    rule.nw_proto = IPv4.PROTOCOL_ICMP;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                } 
            } 
            
            else if (n == "tp-src") {
                rule.wildcard_tp_src = false;
                rule.tp_src = Short.parseShort(jp.getText());
            } 
            
            else if (n == "tp-dst") {
                rule.wildcard_tp_dst = false;
                rule.tp_dst = Short.parseShort(jp.getText());
            } 
            
            else if (n == "priority") {
                rule.priority = Integer.parseInt(jp.getText());
            } 
            
            else if (n == "action") {
                if (jp.getText().equalsIgnoreCase("allow") == true) {
                    rule.action = FirewallRule.FirewallAction.ALLOW;
                } else if (jp.getText().equalsIgnoreCase("deny") == true) {
                    rule.action = FirewallRule.FirewallAction.DENY;
                }
            }
        }

        return rule;
    }

    public static int[] IPCIDRToPrefixBits(String cidr) {
        int ret[] = new int[2];

        // as IP can also be a prefix rather than an absolute address
        // split it over "/" to get the bit range
        String[] parts = cidr.split("/");
        String cidr_prefix = parts[0].trim();
        int cidr_bits = 0;
        if (parts.length == 2) {
            try {
                cidr_bits = Integer.parseInt(parts[1].trim());
            } catch (Exception exp) {
                cidr_bits = 32;
            }
        }
        ret[0] = IPv4.toIPv4Address(cidr_prefix);
        ret[1] = cidr_bits;

        return ret;
    }

    public static boolean checkRuleExists(FirewallRule rule, List<FirewallRule> rules) {
        Iterator<FirewallRule> iter = rules.iterator();
        while (iter.hasNext()) {
            FirewallRule r = iter.next();

            // check if we find a similar rule
            if (rule.isSameAs(r)) {
                return true;
            }
        }

        // no rule matched, so it doesn't exist in the rules
        return false;
    }
}
