/*
 * Zed Attack Proxy (ZAP) and its related class files.
 * 
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 * 
 * 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.zaproxy.zap.extension.keyboard;

import java.text.MessageFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import net.sf.json.JSONObject;

import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.network.HttpMalformedHeaderException;
import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.zap.extension.api.API;
import org.zaproxy.zap.extension.api.ApiException;
import org.zaproxy.zap.extension.api.ApiImplementor;
import org.zaproxy.zap.extension.api.ApiOther;

public class KeyboardAPI extends ApiImplementor {

	private static final String PREFIX = "keyboard";
	
	private static final String OTHER_CHEETSHEET_ACTION_ORDER = "cheatsheetActionOrder";
	private static final String OTHER_CHEETSHEET_KEY_ORDER = "cheatsheetKeyOrder";
	
	private static final String PARAM_INC_UNSET = "incUnset";
	
	private ExtensionKeyboard extension;

	public KeyboardAPI(ExtensionKeyboard extension) {
		this.extension = extension;
		this.addApiOthers(new ApiOther(OTHER_CHEETSHEET_ACTION_ORDER, null, new String[] {PARAM_INC_UNSET}));
		this.addApiOthers(new ApiOther(OTHER_CHEETSHEET_KEY_ORDER, null, new String[] {PARAM_INC_UNSET}));
	}

	@Override
	public String getPrefix() {
		return PREFIX;
	}
	
	public URI getCheatSheetActionURI() throws URIException, NullPointerException {
		return new URI(API.getInstance().getBaseURL(
				API.Format.OTHER, PREFIX, API.RequestType.other, OTHER_CHEETSHEET_ACTION_ORDER, false), 
				true);
	}

	public URI getCheatSheetKeyURI() throws URIException, NullPointerException {
		return new URI(API.getInstance().getBaseURL(
				API.Format.OTHER, PREFIX, API.RequestType.other, OTHER_CHEETSHEET_KEY_ORDER, false), 
				true);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public HttpMessage handleApiOther(HttpMessage msg, String name, JSONObject params) throws ApiException {
		if (OTHER_CHEETSHEET_ACTION_ORDER.equals(name) ||
				OTHER_CHEETSHEET_KEY_ORDER.equals(name)) {
			
			List<KeyboardShortcut> shortcuts = this.extension.getShortcuts();
			
			if (OTHER_CHEETSHEET_ACTION_ORDER.equals(name)) {
				Collections.sort(shortcuts, new Comparator() {
					@Override
					public int compare(Object o1, Object o2) {
						return ((KeyboardShortcut)o1).getName().compareTo(((KeyboardShortcut)o2).getName());
					}});
			} else {
				Collections.sort(shortcuts, new Comparator() {
					@Override
					public int compare(Object o1, Object o2) {
						return ((KeyboardShortcut)o1).getKeyStrokeKeyCodeString().compareTo(
								((KeyboardShortcut)o2).getKeyStrokeKeyCodeString());
					}});
			}
			
			StringBuilder response = new StringBuilder();
			response.append(Constant.messages.getString("keyboard.api.cheatsheet.header"));
			boolean incUnset = this.getParam(params, PARAM_INC_UNSET, false);
			
			for (KeyboardShortcut shortcut : shortcuts) {
				if (incUnset || shortcut.getKeyStrokeKeyCodeString().length() > 0) {
					// Only show actions with actual shortcuts
					response.append(MessageFormat.format(
							Constant.messages.getString("keyboard.api.cheatsheet.tablerow"),
							shortcut.getName(),
							shortcut.getKeyStrokeModifiersString(),
							shortcut.getKeyStrokeKeyCodeString()));
				}
			}
			response.append(Constant.messages.getString("keyboard.api.cheatsheet.footer"));
			
	    	try {
	            msg.setResponseHeader(API.getDefaultResponseHeader("text/html", response.length()));
			} catch (HttpMalformedHeaderException e) {
				throw new ApiException(ApiException.Type.INTERNAL_ERROR, name, e);
			}
	    	msg.setResponseBody(response.toString());
	    	
	    	return msg;

		} else {
			throw new ApiException(ApiException.Type.BAD_OTHER, name);
		}
	}

}

@@ -2525,56 +2525,8 @@
 %09%7D%0A%0A
-%09@SuppressWarnings(%7B %22unchecked%22, %22rawtypes%22 %7D)%0A
 %09@Ov
@@ -2905,32 +2905,50 @@
 , new Comparator
+%3CKeyboardShortcut%3E
 () %7B%0A%09%09%09%09%09@Overr
@@ -2975,32 +2975,52 @@
 compare(
-Object o1, Objec
+KeyboardShortcut o1, KeyboardShortcu
 t o2) %7B%0A
@@ -3032,38 +3032,18 @@
 %09return 
-((KeyboardShortcut)
 o1
-)
 .getName
@@ -3055,38 +3055,18 @@
 mpareTo(
-((KeyboardShortcut)
 o2
-)
 .getName
@@ -3138,16 +3138,34 @@
 mparator
+%3CKeyboardShortcut%3E
 () %7B%0A%09%09%09
@@ -3204,24 +3204,44 @@
 are(
-Object o1, Objec
+KeyboardShortcut o1, KeyboardShortcu
 t o2
@@ -3261,30 +3261,10 @@
 urn 
-((KeyboardShortcut)
 o1
-)
 .get
@@ -3302,39 +3302,10 @@
 eTo(
-%0A%09%09%09%09%09%09%09%09((KeyboardShortcut)
 o2
-)
 .get

Remove warning suppressions in KeyboardAPI