context: /*
   * This file is part of ChronoJump
   *
   * ChronoJump is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *   the Free Software Foundation; either version 2 of the License, or   
   *    (at your option) any later version.
   *    
   * ChronoJump is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
   *    GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * Copyright (C) 2016-2017 Carles Pina
   * Copyright (C) 2016-2021 Xavier de Blas
   */
  
  using System;
  using System.Net;
  using System.Web;
  using System.IO;
  using System.Json;
  using System.Text;
  using System.Collections;
  using System.Collections.Generic; //Dictionary
  using Mono.Unix;
  
  
  public class JsonCompujump : Json
  {
  	private bool django;
  
  	public JsonCompujump(bool django)
  	{
  		this.django = django;
  
  		ResultMessage = "";
  	}
  
  	public Person GetPersonByRFID(string rfid)
  	{
  		connected = false;
  		Person person = new Person(-1);
  
  		// Create a request using a URL that can receive a post.
  		if (! createWebRequest(requestType.AUTHENTICATED, "/api/v1/client/getPlayerByRFID"))
  			return person;
  
  		// Set the Method property of the request to POST.
  		request.Method = "POST";
  
  		// Creates the json object
  		JsonObject json = new JsonObject();
  
  		json.Add("rfid", rfid);
  		
  		// Converts it to a String
  		String js = json.ToString();
  
  		// Writes the json object into the request dataStream
  		Stream dataStream;
  		if(! getWebRequestStream (request, out dataStream, "Cannot get person by RFID."))
  			return person;
  
  		dataStream.Write (Encoding.UTF8.GetBytes(js), 0, js.Length);
  		dataStream.Close ();
  
  		connected = true;
  
  		HttpWebResponse response;
  		if(! getHttpWebResponse (request, out response, "Cannot get person by RFID."))
  			return person;
  
  		string responseFromServer;
  		using (var sr = new StreamReader(response.GetResponseStream()))
  		{
  			responseFromServer = sr.ReadToEnd();
  		}
  
  		LogB.Information("GetPersonByRFID: " + responseFromServer);
  		
  		if(responseFromServer == "")
  			LogB.Information(" Empty "); //never happens
  		else if(responseFromServer == "[]")
  			LogB.Information(" Empty2 "); //when rfid is not on server
  		else {
  			//patheticPersonDeserialize("[[2, \"(playername)\", 82.0, \"253,20,150,13\", \"\"]]");
  			//patheticPersonDeserialize("[[2, \"(playername)\", 82.0, \"253,20,150,13\", \"jugadors/player.jpg\"]]");
  			person = personDeserialize(responseFromServer);
  		}
  
  		return person;
  	}
  
  	public double LastPersonByRFIDHeight = 0;
  	public double LastPersonByRFIDWeight = 0;
  	public string LastPersonByRFIDImageURL = "";
  	public bool LastPersonJustInserted = false;
  	private Person personDeserialize(string strPerson)
  	{
  		JsonValue jsonPerson = JsonValue.Parse(strPerson);
  
  		Int32 id = jsonPerson ["user_id"];
  		string player = jsonPerson ["name"];
  		double weight = jsonPerson ["weight"];
  		double height = jsonPerson ["height"];
  		string rfid = jsonPerson ["rfid"];
  		string image = jsonPerson ["image_thumbnail"];
  
  		LastPersonByRFIDHeight = height;
  		LastPersonByRFIDWeight = weight;
  		LastPersonByRFIDImageURL = image;
  
  		Person personTemp = SqlitePerson.Select(false, id);
  		/*
  		 * if personTemp == -1, need to insert this person
  		 * LastPersonJustInserted will be used:
  		 * 	to insert person at person.cs
  		 * 	to know if (it's new person or RFID changed) at gui/networks.cs
  		 */
  		LastPersonJustInserted = (personTemp.UniqueID == -1);
  
  		return new Person(LastPersonJustInserted, id, player, rfid, image);
  	}
  
  
  	//Retrieve images from server
  	private string getImagesUrl()
  	{
  		//Networks v3
  		return serverUrl;
  		/*
  		int posOfLastColon = serverUrl.LastIndexOf(':');
  		if(django) //Networks v2
  			return serverUrl.Substring(0, posOfLastColon) + ":8000/media/";
  		else //Networks v1
  			return serverUrl.Substring(0, posOfLastColon) + ":5000/static/images/photos/";
  		*/
  	}
  
  	//imageHalfUrl is "jugadors/*.jpg"
  	public bool DownloadImage(string imageHalfUrl, int personID)
  	{
  		try {
  			using (WebClient client = new WebClient())
  			{
  				LogB.Information ("Compujump DownloadImage!!");
  				LogB.Information (getImagesUrl() + imageHalfUrl);
  				LogB.Information (Path.Combine(Path.GetTempPath(), personID.ToString()));
  				client.DownloadFile(new Uri(getImagesUrl() + imageHalfUrl),
  						Path.Combine(Path.GetTempPath(), personID.ToString()));
  			}
  		} catch {
  			LogB.Warning("Compujump DownloadImage catched");
  			return false;
  		}
  
  		return true;
  	}
  
  	public string GetTasksResponse (int personID, int stationID)
  	{
  		connected = false;
  
  		// Create a request using a URL that can receive a post.
  		if (! createWebRequest(requestType.AUTHENTICATED, "/api/v1/client/getTasks"))
  			return "";
  
  		// Set the Method property of the request to POST.
  		request.Method = "POST";
  
  		// Creates the json object
  		JsonObject json = new JsonObject();
  		json.Add("player_id", personID.ToString());
  
  		// Converts it to a String
  		String js = json.ToString();
  
  		LogB.Debug("GetTasks params: " + js + "\n");
  		// Writes the json object into the request dataStream
  		Stream dataStream;
  		if(! getWebRequestStream (request, out dataStream, "Cannot get tasks."))
  			return "";
  
  		dataStream.Write (Encoding.UTF8.GetBytes(js), 0, js.Length);
  		dataStream.Close ();
  
  		HttpWebResponse response;
  		if(! getHttpWebResponse (request, out response, "Cannot get tasks."))
  			return "";
  
  		string responseFromServer;
  		using (var sr = new StreamReader(response.GetResponseStream()))
  		{
  			responseFromServer = sr.ReadToEnd();
  		}
  
  		LogB.Information("GetTasks: " + responseFromServer);
  
  		connected = true;
  
  		if(responseFromServer == "" || responseFromServer == "[]")
  		{
  			LogB.Information(" Empty ");
  			return "";
  		}
  
  		return responseFromServer;
  	}
  
  	public bool UpdateTask(int taskId, int done)
  	{
  		LogB.Information("At UpdateTask");
  		// Create a request using a URL that can receive a post.
  		if (! createWebRequest(requestType.AUTHENTICATED, "/api/v1/client/updateTask"))
  			return false;
  
  		// Set the Method property of the request to POST.
  		request.Method = "POST";
  
  		// Creates the json object
  		JsonObject json = new JsonObject();
  		json.Add("task_id", taskId);
  		json.Add("done", done);
  
  		// Converts it to a String
  		String js = json.ToString();
  
  		// Writes the json object into the request dataStream
  		Stream dataStream;
  		if(! getWebRequestStream (request, out dataStream, "Cannot update task"))
  			return false;
  
  		dataStream.Write (Encoding.UTF8.GetBytes(js), 0, js.Length);
  		dataStream.Close ();
  
  		// Get the response.
  		WebResponse response;
  		if(! getWebResponse (request, out response, "Cannot update task"))
  			return false;
  
  		// Display the status (will be 202, CREATED)
  		Console.WriteLine (((HttpWebResponse)response).StatusDescription);
  
  		// Clean up the streams.
  		dataStream.Close ();
  		response.Close ();
  
  		this.ResultMessage = "Update task sent.";
  		return true;
  	}
  
  	//get pending tasks on other stations
  	public List<StationCount> GetOtherStationsWithPendingTasks(int personID, int stationID)
  	{
  		// Create a request using a URL that can receive a post.
  		if (! createWebRequest(requestType.AUTHENTICATED, "/api/v1/client/getOtherStationsWithPendingTasks"))
  			return new List<StationCount>();
  
  		// Set the Method property of the request to POST.
  		request.Method = "POST";
  
  		// Creates the json object
  		JsonObject json = new JsonObject();
  		json.Add("player_id", personID.ToString());
  
  		// Converts it to a String
  		String js = json.ToString();
  
  		// Writes the json object into the request dataStream
  		Stream dataStream;
  		if(! getWebRequestStream (request, out dataStream, Catalog.GetString("Could not get tasks from other sessions.")))
  			return new List<StationCount>();
  
  		dataStream.Write (Encoding.UTF8.GetBytes(js), 0, js.Length);
  		dataStream.Close ();
  
  		HttpWebResponse response;
  		if(! getHttpWebResponse (request, out response, Catalog.GetString("Could not get tasks from other sessions.")))
  			return new List<StationCount>();
  
  		string responseFromServer;
  		using (var sr = new StreamReader(response.GetResponseStream()))
  		{
  			responseFromServer = sr.ReadToEnd();
  		}
  
  		LogB.Information("GetOtherStationsWithPendingTasks: " + responseFromServer);
  
  		if(responseFromServer == "" || responseFromServer == "[]")
  		{
  			LogB.Information(" Empty ");
  			return new List<StationCount>();
  		}
  
  		//return taskDeserializeFromServer (responseFromServer);
  		List<StationCount> stations = new List<StationCount>();
  		JsonValue jsonStations = JsonValue.Parse (responseFromServer);
  
  		foreach (JsonValue jsonStation in jsonStations)
  		{
  			string stationName = jsonStation ["station_name"];
  			int tasksCount = jsonStation ["tasks_count"];
  			stations.Add(new StationCount(stationName, tasksCount));
  		}
  		return stations;
  	}
  
  	//stationType can be GRAVITATORY or INERTIAL
  	public List<EncoderExercise> GetStationExercises(int stationId, Constants.EncoderGI stationType)
  	{
  		List<EncoderExercise> ex_list = new List<EncoderExercise>();
  
  		// Create a request using a URL that can receive a post.
  		if (! createWebRequest(requestType.AUTHENTICATED, "/api/v1/client/getStationExercises"))
  			return ex_list;
  
  		// Set the Method property of the request to GET.
  		request.Method = "GET";
  
  		HttpWebResponse response;
  		if(! getHttpWebResponse (request, out response, Catalog.GetString("Could not get station exercises.")))
  			return ex_list;
  
  		string responseFromServer;
  		using (var sr = new StreamReader(response.GetResponseStream()))
  		{
  			responseFromServer = sr.ReadToEnd();
  		}
  
  		LogB.Information("GetStationExercises: " + responseFromServer);
  
  		if(responseFromServer == "")
  			LogB.Information(" Empty "); //never happens
  		else if(responseFromServer == "[]")
  			LogB.Information(" Empty2 "); //when rfid is not on server
  		else {
  			ex_list = stationExercisesDeserialize(responseFromServer, stationId, stationType);
  		}
  
  		return ex_list;
  	}
  	private List<EncoderExercise> stationExercisesDeserialize(string str, int stationId, Constants.EncoderGI stationType)
  	{
  
gt: 		List<EncoderExercise> ex_list = new List<EncoderExercise>();