/*
 * Copyright 2015 Open Networking Laboratory
 * Originally created by Pengfei Lu, Network and Cloud Computing Laboratory, Dalian University of Technology, China
 * Advisers: Keqiu Li, Heng Qi and Haisheng Yu
 * This work is supported by the State Key Program of National Natural Science of China(Grant No. 61432002)
 * and Prospective Research Project on Future Networks in Jiangsu Future Networks Innovation Institute.
 *
 * 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.onos.acl;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onlab.packet.IPv4;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

// FIXME: This does now follow REST-full principles and should be refactored.
/**
 * Manage ACL rules.
 */
@Path("")
public class AclWebResource extends AbstractWebResource {

    private final Logger log = LoggerFactory.getLogger(getClass());

    /**
     * Processes user's GET HTTP request for querying ACL rules.
     * @return response to the request
     */
    @GET
    public Response queryAclRule() {
        List<AclRule> rules = get(AclService.class).getAclRules();
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode root = mapper.createObjectNode();
        ArrayNode arrayNode = mapper.createArrayNode();
        for (AclRule rule : rules) {
            ObjectNode node = mapper.createObjectNode();
            node.put("id", rule.id().toString());
            if (rule.srcIp() != null) {
                node.put("srcIp", rule.srcIp().toString());
            }
            if (rule.dstIp() != null) {
                node.put("dstIp", rule.dstIp().toString());
            }
            if (rule.ipProto() != 0) {
                switch (rule.ipProto()) {
                    case IPv4.PROTOCOL_ICMP:
                        node.put("ipProto", "ICMP");
                        break;
                    case IPv4.PROTOCOL_TCP:
                        node.put("ipProto", "TCP");
                        break;
                    case IPv4.PROTOCOL_UDP:
                        node.put("ipProto", "UDP");
                        break;
                    default:
                        break;
                }
            }
            if (rule.dstTpPort() != 0) {
                node.put("dstTpPort", rule.dstTpPort());
            }
            node.put("action", rule.action().toString());
            arrayNode.add(node);
        }
        root.set("ACL rules", arrayNode);
        return Response.ok(root.toString(), MediaType.APPLICATION_JSON_TYPE).build();
    }

    /**
     * Processes user's POST HTTP request for add ACL rules.
     * @param stream input stream
     * @return response to the request
     */
    @POST
    @Path("add")
    public Response addAclRule(InputStream stream) {
        AclRule newRule;
        try {
            newRule = jsonToRule(stream);
        } catch (Exception e) {
            return Response.ok("{\"status\" : \"Failed! " + e.getMessage() + "\"}").build();
        }

        String status;
        if (get(AclService.class).addAclRule(newRule)) {
            status = "Success! New ACL rule is added.";
        } else {
            status = "Failed! New ACL rule matches an existing rule.";
        }
        return Response.ok("{\"status\" : \"" + status + "\"}").build();
    }

    /**
     * Processes user's GET HTTP request for removing ACL rule.
     * @param id ACL rule id (in hex string format)
     * @return response to the request
     */
    @GET
    @Path("remove/{id}")
    public Response removeAclRule(@PathParam("id") String id) {
        String status;
        RuleId ruleId = new RuleId(Long.parseLong(id.substring(2), 16));
        if (get(AclStore.class).getAclRule(ruleId) == null) {
            status = "Failed! There is no ACL rule with this id.";
        } else {
            get(AclService.class).removeAclRule(ruleId);
            status = "Success! ACL rule(id:" + id + ") is removed.";
        }
        return Response.ok("{\"status\" : \"" + status + "\"}").build();
    }

    /**
     * Processes user's GET HTTP request for clearing ACL.
     * @return response to the request
     */
    @GET
    @Path("clear")
    public Response clearACL() {
        get(AclService.class).clearAcl();
        return Response.ok("{\"status\" : \"ACL is cleared.\"}").build();
    }

    /**
     * Exception class for parsing a invalid ACL rule.
     */
    private class AclRuleParseException extends Exception {
        public AclRuleParseException(String message) {
            super(message);
        }
    }

    /**
     * Turns a JSON string into an ACL rule instance.
     */
    private AclRule jsonToRule(InputStream stream) throws AclRuleParseException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(stream);
        JsonParser jp = jsonNode.traverse();
        AclRule.Builder rule = AclRule.builder();
        jp.nextToken();
        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
            throw new AclRuleParseException("Expected START_OBJECT");
        }

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

            String key = jp.getCurrentName();
            jp.nextToken();
            String value = jp.getText();
            if ("".equals(value)) {
                continue;
            }

            if ("srcIp".equals(key)) {
                rule.srcIp(value);
            } else if ("dstIp".equals(key)) {
                rule.dstIp(value);
            } else if ("ipProto".equals(key)) {
                if ("TCP".equalsIgnoreCase(value)) {
                    rule.ipProto(IPv4.PROTOCOL_TCP);
                } else if ("UDP".equalsIgnoreCase(value)) {
                    rule.ipProto(IPv4.PROTOCOL_UDP);
                } else if ("ICMP".equalsIgnoreCase(value)) {
                    rule.ipProto(IPv4.PROTOCOL_ICMP);
                } else {
                    throw new AclRuleParseException("ipProto must be assigned to TCP, UDP, or ICMP.");
                }
            } else if ("dstTpPort".equals(key)) {
                try {
                    rule.dstTpPort(Short.parseShort(value));
                } catch (NumberFormatException e) {
                    throw new AclRuleParseException("dstTpPort must be assigned to a numerical value.");
                }
            } else if ("action".equals(key)) {
                if (!"allow".equalsIgnoreCase(value) && !"deny".equalsIgnoreCase(value)) {
                    throw new AclRuleParseException("action must be assigned to ALLOW or DENY.");
                }
                if ("allow".equalsIgnoreCase(value)) {
                    rule.action(AclRule.Action.ALLOW);
                }
            }
        }
        return rule.build();
    }

}