/**
*    Copyright 2011, Big Switch Networks, Inc. 
*    Originally created by David Erickson, Stanford University
* 
*    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 net.floodlightcontroller.staticflowentry.web;

import java.util.Map;

import net.floodlightcontroller.core.annotations.LogMessageCategory;
import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;

import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Pushes a static flow entry to the storage source
 * @author alexreimers
 *
 */
@LogMessageCategory("Static Flow Pusher")
public class StaticFlowEntryPusherResource extends ServerResource {
    protected final static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class);
    
    /**
     * Checks to see if the user matches IP information without
     * checking for the correct ether-type (2048).
     * @param rows The Map that is a string representation of
     * the static flow.
     * @reutrn True if they checked the ether-type, false otherwise
     */
    private boolean checkMatchIp(Map<String, Object> rows) {
        boolean matchEther = false;
        String val = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE);
        if (val != null) {
            int type = 0;
            // check both hex and decimal
            if (val.startsWith("0x")) {
                type = Integer.parseInt(val.substring(2), 16);
            } else {
                try {
                    type = Integer.parseInt(val);
                } catch (NumberFormatException e) { /* fail silently */}
            }
            if (type == 2048) matchEther = true;
        }
        
        if ((rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) || 
                rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC) ||
                rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO) ||
                rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_TOS)) &&
                (matchEther == false))
            return false;
        
        return true;
    }
    
    /**
     * Takes a Static Flow Pusher string in JSON format and parses it into
     * our database schema then pushes it to the database.
     * @param fmJson The Static Flow Pusher entry in JSON format.
     * @return A string status message
     */
    /*
    @Post
    @LogMessageDoc(level="ERROR",
        message="Error parsing push flow mod request: {request}",
        explanation="An invalid request was sent to static flow pusher",
        recommendation="Fix the format of the static flow mod request")
    public String store(String fmJson) {
        IStorageSourceService storageSource =
                (IStorageSourceService)getContext().getAttributes().
                    get(IStorageSourceService.class.getCanonicalName());
        
        Map<String, Object> rowValues;
        try {
            rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson);
            String status = null;
            if (!checkMatchIp(rowValues)) {
                status = "Warning! Pushing a static flow entry that matches IP " +
                        "fields without matching for IP payload (ether-type 2048) will cause " +
                        "the switch to wildcard higher level fields.";
                log.error(status);
            } else {
                status = "Entry pushed";
            }
            storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, rowValues);
            return ("{\"status\" : \"" + status + "\"}");
        } catch (IOException e) {
            log.error("Error parsing push flow mod request: " + fmJson, e);
            e.printStackTrace();
            return "{\"status\" : \"Error! Could not parse flod mod, see log for details.\"}";
        }
    }
    
    @Delete
    @LogMessageDoc(level="ERROR",
        message="Error deleting flow mod request: {request}",
        explanation="An invalid delete request was sent to static flow pusher",
        recommendation="Fix the format of the static flow mod request")
    public String del(String fmJson) {
        IStorageSourceService storageSource =
                (IStorageSourceService)getContext().getAttributes().
                    get(IStorageSourceService.class.getCanonicalName());
        String fmName = null;
        if (fmJson == null) {
            return "{\"status\" : \"Error! No data posted.\"}";
        }
        try {
            fmName = StaticFlowEntries.getEntryNameFromJson(fmJson);
            if (fmName == null) {
                return "{\"status\" : \"Error deleting entry, no name provided\"}";
            }
        } catch (IOException e) {
            log.error("Error deleting flow mod request: " + fmJson, e);
            e.printStackTrace();
            return "{\"status\" : \"Error deleting entry, see log for details\"}";
        }
        
        storageSource.deleteRowAsync(StaticFlowEntryPusher.TABLE_NAME, fmName);
        return "{\"status\" : \"Entry " + fmName + " deleted\"}";
    }
    */
}
