//
//  Copyright © 2016 Zello. All rights reserved.
//

package com.zellowork.apiwrapper;

import android.util.Log;

import org.json.JSONObject;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class APITest {

	static String TAG = "APITest";

	ZelloAPI api;

	public APITest(String host, String apiKey, String username, String password) {
		api = new ZelloAPI(host, apiKey);
		authenticate(username, password);
	}

	void authenticate(String username, String password) {
		api.authenticate(username, password, new ResultCompletionHandler() {
			@Override
			public void onResult(boolean success, JSONObject response, Exception exception) {
				if (success) {
					startTesting();
				}
			}
		});
	}

	void startTesting() {
		api.getUsers(null, false, null, null, null, new ResultCompletionHandler() {
			@Override
			public void onResult(boolean success, JSONObject response, Exception exception) {
				Log.w(TAG, "getUsers: " + Boolean.toString(success));
				if (success) {
					Log.w(TAG, response.toString());
				}

				api.getChannels(null, null, null, new ResultCompletionHandler() {
					@Override
					public void onResult(boolean success, JSONObject response, Exception exception) {
						Log.w(TAG, "getChannels: " + Boolean.toString(success));
						if (success) {
							Log.w(TAG, response.toString());
						}

						// Add or update user
						Map<String, String> userMap = new HashMap<>();
						userMap.put("name", "zelloapi_test");
						userMap.put("password", MD5("test"));
						userMap.put("email", "support@zello.com");
						userMap.put("full_name", "API Test 'На здоровье'"); // UTF-8 is fully supported
						api.saveUser(userMap, new ResultCompletionHandler() {
							@Override
							public void onResult(boolean success, JSONObject response, Exception exception) {
								Log.w(TAG, "saveUser: " + Boolean.toString(success));

								// List users again -- look the new user is there
								api.getUsers(null, false, null, null, null, new ResultCompletionHandler() {
									@Override
									public void onResult(boolean success, JSONObject response, Exception exception) {
										Log.w(TAG, "getUsers: " + Boolean.toString(success));

										if (success) {
											Log.w(TAG, response.toString());
										}

										continueTesting();
									}
								});
							}
						});
					}
				});
			}
		});
	}

	void continueTesting() {
		// Add channel
		api.addChannel("Test channel", null, null, new ResultCompletionHandler() {
			@Override
			public void onResult(boolean success, JSONObject response, Exception exception) {
				Log.w(TAG, "addChannel: " + Boolean.toString(success));

				ArrayList<String> users = new ArrayList<>();
				users.add("zelloapi_test");

				// Add user to a channel
				api.addToChannel("Test channel", users, new ResultCompletionHandler() {
					@Override
					public void onResult(boolean success, JSONObject response, Exception exception) {
						Log.w(TAG, "addToChannel: " + Boolean.toString(success));

						// List channels again
						api.getChannels(null, null, null, new ResultCompletionHandler() {
							@Override
							public void onResult(boolean success, JSONObject response, Exception exception) {
								Log.w(TAG, "getChannels: " + Boolean.toString(success));

								if (success) {
									Log.w(TAG, response.toString());
								}

								// Create channel role

								Map<String, Object> channelRoleDictionary = new HashMap<>();
								channelRoleDictionary.put("listen_only", false);
								channelRoleDictionary.put("no_disconnect", true);
								channelRoleDictionary.put("allow_alerts", false);
								String[] toArray = new String[]{};
								channelRoleDictionary.put("to", toArray);

								api.saveChannelRole("Test channel", "Dispatcher", channelRoleDictionary, new ResultCompletionHandler() {
									@Override
									public void onResult(boolean success, JSONObject response, Exception exception) {
										Log.w(TAG, "saveChannelRole: " + Boolean.toString(success));

										Map<String, Object> channelRoleDictionary = new HashMap<>();
										channelRoleDictionary.put("listen_only", true);
										channelRoleDictionary.put("no_disconnect", false);
										channelRoleDictionary.put("allow_alerts", true);
										String[] toArray = new String[] { "Dispatcher" };
										channelRoleDictionary.put("to", toArray);

										api.saveChannelRole("Test channel", "Driver", channelRoleDictionary, new ResultCompletionHandler() {
											@Override
											public void onResult(boolean success, JSONObject response, Exception exception) {
												Log.w(TAG, "saveChannelRole: " + Boolean.toString(success));

												// List channel roles
												api.getChannelsRoles("Test channel", new ResultCompletionHandler() {
													@Override
													public void onResult(boolean success, JSONObject response, Exception exception) {
														Log.w(TAG, "getChannelsRoles: " + Boolean.toString(success));

														if (success) {
															Log.w(TAG, response.toString());
														}

														cleanUp();
													}
												});
											}
										});
									}
								});
							}
						});
					}
				});
			}
		});
	}

	void cleanUp() {
		// Remove the channel
		ArrayList<String> channelNames = new ArrayList<>();
		channelNames.add("Test channel");
		api.deleteChannels(channelNames, new ResultCompletionHandler() {
			@Override
			public void onResult(boolean success, JSONObject response, Exception exception) {
				Log.w(TAG, "deleteChannels: " + Boolean.toString(success));

				// Delete the user we just added
				ArrayList<String> users = new ArrayList<>();
				users.add("zelloapi_test");
				api.deleteUsers(users, new ResultCompletionHandler() {
					@Override
					public void onResult(boolean success, JSONObject response, Exception exception) {
						Log.w(TAG, "deleteUsers: " + Boolean.toString(success));

						// List users one last time -- the new user is gone
						api.getUsers(null, false, null, null, null, new ResultCompletionHandler() {
							@Override
							public void onResult(boolean success, JSONObject response, Exception exception) {
								Log.w(TAG, "getUsers: " + Boolean.toString(success));

								if (success) {
									Log.w(TAG, response.toString());
								}
							}
						});
					}
				});
			}
		});
	}

	private synchronized String MD5(String string) {
		try {
			MessageDigest m = MessageDigest.getInstance("MD5");
			m.reset();
			m.update(string.getBytes());
			byte[] digest = m.digest();
			BigInteger bigInt = new BigInteger(1, digest);

			return bigInt.toString(16);
		} catch (Exception e) {
			// Empty
		}

		return null;
	}

}

@@ -730,24 +730,87 @@
 xception) %7B%0A
+%09%09%09%09Log.w(TAG, %22authenticate: %22 + Boolean.toString(success));%0A%0A
 %09%09%09%09if (succ

Add authentication logging to test