package kz.istt.locust;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;

/*import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;*/
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import tctable.TCTable;
//import org.apache.http.entity.MultipartEntity;

/** Синхронизация данных с сервером
 * Нужно сделать глобальным
 * */
public class MySynchronizationNew
{
	//public static String URL="https://ccalm.org";
	//public static String URL="http://192.168.0.89:8080/CCALM";
	public static String URL="https://ccalm.org";
	private Context m_context=null;
	private SendData sd=null;

	public MySynchronizationNew(Context context)
	{
		m_context=context;
	}

	public void Synch()
	{
		if(sd!=null && sd.getCount()!=0)
			return;

		sd=new SendData(m_context);

		sd.addTask("frmlocust");
		sd.addTask("frmlocustdel");

		sd.addTask("borns"); //Справочник отрождение "Начало", "Массовое".
		sd.addTask("countries");
		sd.addTask("countriesregions");
		sd.addTask("locuststypes");
		sd.addTask("sprayers");
		sd.addTask("sprayers_types");
		sd.addTask("fledgling");
		sd.addTask("list_density");
		sd.addTask("list_phase");
		sd.addTask("list_directions"); //Стороны света (направления)
		sd.addTask("list_damage"); //Справочник степень повреждения растительного покрова
		sd.addTask("list_mortality"); //Справочник степень повреждения растительного покрова
		sd.addTask("list_greenery");
		sd.addTask("list_biotope");
		sd.addTask("list_cover");
		sd.addTask("list_age");
		sd.addTask("list_actions");
		sd.addTask("list_paintings");
		sd.addTask("list_behaviors");
		sd.addTask("list_breeding");
		sd.addTask("list_capacities");
		sd.addTask("list_markings");
		sd.addTask("list_containers");
		sd.addTask("list_vegetation");
		sd.addTask("list_formulation");
		sd.addTask("list_height");
		sd.addTask("list_enemies");
		sd.addTask("list_purpose");
		sd.addTask("list_impact");
		sd.addTask("terminals");
		sd.addTask("_languages");
		sd.addTask("_translations");

		sd.addTask("files");

		sd.execute();
	}

	public int getCount()
	{
		if(sd!=null)
			return sd.getCount();
		else
			return 0;
	}

	public class SendData extends AsyncTask<Void, Void, Void>
	{
		private Context mContext;
		//private String mTableName;
		private ArrayList<String> mTList = new ArrayList<String>(); //Защищёный список
		private Semaphore mSemaphore = null; //Семафор для доступа к списку заданий

		public void addTask(String tableName)
		{
			try
			{
				mSemaphore.acquire();
				mTList.add(tableName);
			} catch (InterruptedException e) {
				//e.printStackTrace();
				Log.e("CCALM", "Error: ", e);
			} finally
			{	mSemaphore.release();
			}
		}

		public int getCount()
		{
			int result=0;
			try
			{
				mSemaphore.acquire();
				result=mTList.size();
			} catch (InterruptedException e) {
				//e.printStackTrace();
				Log.e("CCALM", "Error: ", e);
			} finally
			{	mSemaphore.release();
			}
			return result;
		}

		SendData(Context context)
		{
			mContext = context;
			mSemaphore = new Semaphore(1);
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		//Отправляю файлик на сервер
		protected boolean sendFile(String fName)
		{
			boolean result=false;
/*			try
			{
				HttpClient httpClient = new DefaultHttpClient();
				httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
				HttpPost httpPost = new HttpPost(MySynchronizationNew.URL+"/get/?fn=6");

				File file = new File(fName);
				if(file.exists())
				{
					MultipartEntity mpEntity = new MultipartEntity();
					ContentBody cbFile = new FileBody(file, "image/jpeg");
					mpEntity.addPart("file", cbFile);
					httpPost.setEntity(mpEntity);
				}
				HttpResponse response = httpClient.execute(httpPost);
				if(response != null)
				{
					StringReader sr = new StringReader(EntityUtils.toString(response.getEntity(),"utf-8"));
					InputSource is = new InputSource(sr);
					DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
					try
					{
						DocumentBuilder builder = factory.newDocumentBuilder();
						Document doc = null;
						try
						{
							doc = builder.parse(is);
							Element root = doc.getDocumentElement();
							result= XMLTools.getCDATAValue(root).equals("0"); //Признак что успешно отправили на сервер файл
						} catch (Exception e)
						{
						}
					} catch (Exception e) {
					}
				}
			} catch (UnsupportedEncodingException e)
			{
			} catch (ClientProtocolException e)
			{
			} catch (IOException e)
			{
			}*/
			return result;
		}

		Document sendXML(String url, String xml)
		{
			Document doc=null;
/*
			HttpClient httpClient = new DefaultHttpClient();
			httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

			HttpPost httpPost = new HttpPost(url);

			httpPost.addHeader("Content-Type", "application/xml");

			StringEntity entity = null;
			entity = new StringEntity(xml, "UTF-8");

			entity.setContentType("application/xml");
			httpPost.setEntity(entity);
			HttpResponse response=null;
			try {
				response = httpClient.execute(httpPost);
			} catch (IOException e) {
				e.printStackTrace();
			}

			if(response != null)
			{
				xml="";
				try {
					xml = EntityUtils.toString(response.getEntity(),"utf-8");
				} catch (IOException e) {
					e.printStackTrace();
				}
				StringReader sr = new StringReader(xml);
				InputSource is = new InputSource(sr);
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
				DocumentBuilder builder = null;
				try {
					builder = factory.newDocumentBuilder();
					doc = builder.parse(is);
				} catch (ParserConfigurationException e) {
					e.printStackTrace();
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
*/
			return doc;
		}

		@Override
		protected Void doInBackground(Void... params)
		{
/*
			while(true)
			{
				String tableName="";
				try
				{
					mSemaphore.acquire();

					if(mTList.size()==0) break;
					tableName=mTList.get(0);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally
				{	mSemaphore.release();
				}

				Log.e("CCALM", "tableName = " + tableName);

				DbOpenHelper dboh=null;
				try
				{
					dboh = new DbOpenHelper(mContext);

					if(tableName.equals("frmlocust"))
					{
						//Отправляю файлы на сервер
						SQLiteDatabase db = dboh.getReadableDatabase();

						Cursor cursor;
						//image1
						cursor = db.rawQuery("select uid,image_name1 from frmlocust where image_name1 is not null and image_send1=0 and filled=1;", null);
						if (cursor.moveToFirst())
						{
							if(sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"))))
							{
								ContentValues cv = new ContentValues();
								cv.put("image_send1", 1); //Отмечаем как отправленное
								db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
								try {
									db.update("frmlocust", cv, "uid = ?", new String[] { String.valueOf(cursor.getString(cursor.getColumnIndex("uid"))) });
									db.setTransactionSuccessful();
								}catch(Exception e){
									e.printStackTrace();
								} finally {
									db.endTransaction();
								}
							}
						}
						cursor.close();
						//image2
						cursor = db.rawQuery("select uid,image_name2 from frmlocust where image_name2 is not null and image_send2=0 and filled=1;", null);
						if (cursor.moveToFirst())
						{
							if(sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"))))
							{
								ContentValues cv = new ContentValues();
								cv.put("image_send1", 1); //Отмечаем как отправленное
								db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
								try {
									db.update("frmlocust", cv, "uid = ?", new String[] { String.valueOf(cursor.getString(cursor.getColumnIndex("uid"))) });
									db.setTransactionSuccessful();
								}catch(Exception e){
									e.printStackTrace();
								} finally {
									db.endTransaction();
								}
							}
						}
						cursor.close();
						//image3
						cursor = db.rawQuery("select uid,image_name3 from frmlocust where image_name3 is not null and image_send3=0 and filled=1;", null);
						if (cursor.moveToFirst())
						{
							if(sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1"))))
							{
								ContentValues cv = new ContentValues();
								cv.put("image_send1", 1); //Отмечаем как отправленное
								db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
								try {
									db.update("frmlocust", cv, "uid = ?", new String[] { String.valueOf(cursor.getString(cursor.getColumnIndex("uid"))) });
									db.setTransactionSuccessful();
								}catch(Exception e){
									e.printStackTrace();
								} finally {
									db.endTransaction();
								}
							}
						}
						cursor.close();

						//Отправляю данные в виде XML
						cursor = db.rawQuery("select * from frmlocust where filled=1 and send=0", null);
						if(cursor.moveToFirst())
						{
							do{
								String xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
								xml+="<metadata fn=\"4\">";
								for(int i=0;i<cursor.getColumnCount();i++)
								{
									String val=cursor.getString(i);
									if(val==null) val="";
									xml+="	<"+cursor.getColumnName(i)+"><![CDATA["+val+"]]></"+cursor.getColumnName(i)+">\n";
								}
								xml+="</metadata>";
								Document doc = sendXML(MySynchronizationNew.URL+"/get/",xml);
								if(doc!=null)
								{
									//Incoming XML: <?xml version="1.0" encoding="utf-8"?><metadata fn="4" reqid=""><uid><![CDATA[0a16990f9f82488b8ccf4a4cb6411904]]></uid></metadata>
									Element root = doc.getDocumentElement();
									String uid= XMLTools.getCDATAValue(XMLTools.findFirstNode(root,"uid"));
									if(uid!="" || uid!="null")
									{
										ContentValues cv = new ContentValues();
										cv.put("send", 1); //Отмечаем как отправленное
										db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
										try {
											db.update("frmlocust", cv, "uid = ?", new String[] { String.valueOf(uid) });
											db.setTransactionSuccessful();
										}catch(Exception e){
											e.printStackTrace();
										} finally {
											db.endTransaction();
										}
									}
								}
							}while (cursor.moveToNext());
						}
						cursor.close();



					}else if(tableName.equals("frmlocustdel")) {
						//Отправляю файлы на сервер
						SQLiteDatabase db = dboh.getReadableDatabase();

						Cursor cursor;
						//image1
						cursor = db.rawQuery("select uid,image_name1 from frmlocustdel where image_send1=0 and filled=1;", null);
						if (cursor.moveToFirst()) {
							if (sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1")))) {
								ContentValues cv = new ContentValues();
								cv.put("image_send1", 1); //Отмечаем как отправленное
								db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
								try {
									db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(cursor.getString(cursor.getColumnIndex("uid")))});
									db.setTransactionSuccessful();
								} finally {
									db.endTransaction();
								}
							}
						}
						cursor.close();
						//image2
						cursor = db.rawQuery("select uid,image_name2 from frmlocustdel where image_send2=0 and filled=1;", null);
						if (cursor.moveToFirst()) {
							if (sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1")))) {
								ContentValues cv = new ContentValues();
								cv.put("image_send1", 1); //Отмечаем как отправленное
								db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
								try {
									db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(cursor.getString(cursor.getColumnIndex("uid")))});
									db.setTransactionSuccessful();
								} finally {
									db.endTransaction();
								}
							}
						}
						cursor.close();
						//image3
						cursor = db.rawQuery("select uid,image_name3 from frmlocustdel where image_send3=0 and filled=1;", null);
						if (cursor.moveToFirst()) {
							if (sendFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Locust/" + cursor.getString(cursor.getColumnIndex("image_name1")))) {
								ContentValues cv = new ContentValues();
								cv.put("image_send1", 1); //Отмечаем как отправленное
								db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
								try {
									db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(cursor.getString(cursor.getColumnIndex("uid")))});
									db.setTransactionSuccessful();
								} finally {
									db.endTransaction();
								}
							}
						}
						cursor.close();

						//Отправляю данные в виде XML
						cursor = db.rawQuery("select * from frmlocustdel where filled=1 and send=0", null);
						if (cursor.moveToFirst()) {
							do {
								String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
								xml += "<metadata fn=\"5\">";
								for (int i = 0; i < cursor.getColumnCount(); i++) {
									String val = cursor.getString(i);
									if (val == null) val = "";
									xml += "	<" + cursor.getColumnName(i) + "><![CDATA[" + val + "]]></" + cursor.getColumnName(i) + ">\n";
								}
								xml += "</metadata>";
								Document doc = sendXML(MySynchronizationNew.URL + "/get/", xml);
								if (doc != null) {
									//Incoming XML: <?xml version="1.0" encoding="utf-8"?><metadata fn="4" reqid=""><uid><![CDATA[0a16990f9f82488b8ccf4a4cb6411904]]></uid></metadata>
									Element root = doc.getDocumentElement();
									String uid = XMLTools.getCDATAValue(XMLTools.findFirstNode(root, "uid"));
									if (!uid.equals("") || !uid.equals("null")) {
										ContentValues cv = new ContentValues();
										cv.put("send", 1); //Отмечаем как отправленное
										db.beginTransaction(); //Вроде как защита от многопоточности (для сервиса)
										try {
											db.update("frmlocustdel", cv, "uid = ?", new String[]{String.valueOf(uid)});
											db.setTransactionSuccessful();
										} finally {
											db.endTransaction();
										}
									}
								}
							} while (cursor.moveToNext());
						}
						cursor.close();
					}else if(tableName.equals("files"))
					{

					}else { //Все остальные стравочники

						try {
							String seq = "0";

							SQLiteDatabase db = dboh.getReadableDatabase();
							Cursor cursor = db.rawQuery("select max(seq) as seq from " + tableName + ";", null);
							if (cursor.moveToFirst()) {
								seq = cursor.getString(cursor.getColumnIndex("seq"));
							}
							if (seq == null) seq = "0";
							cursor.close();

							//Отправляем данные на сервер
							HttpClient httpClient = new DefaultHttpClient();
							httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

							//String url = MySynchronizationNew.URL + "/get/?fn=1&r=0&n=" + tableName + "&s=" + seq + "&l=1000";
							String url = MySynchronizationNew.URL + "/get/?fn=1&r=0&n=" + tableName + "&s=0&l=1000";

							HttpPost httpPost = new HttpPost(url);
							HttpResponse response = httpClient.execute(httpPost);
							if (response != null) {
								TCTable tbl = new TCTable("", 0);
								if (tbl.OpenTableH(new ByteArrayInputStream(EntityUtils.toByteArray(response.getEntity())))) {
									dboh.updateTable(tbl);
								}
							}else
							{
								Log.e("CCALM", "Error load table \"" + tableName + "\";");
							}


						} catch (ClientProtocolException e) {
							Log.e("CCALM", "ClientProtocolException = " + e.toString());
						} catch (IOException e) {
							Log.e("CCALM", "IOException = " + e.toString());
						}
					}

				} finally
				{
					if(dboh!=null)
						dboh.close();
				}

				//Удаляю после выполнения задания (а то блокировало базу и вылетали ошибки)
				try
				{
					mSemaphore.acquire();
					mTList.remove(0);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally
				{	mSemaphore.release();
				}
			}
			Log.e("CCALM", "END SYNCHONIZATION");
 */
			return null;
		}

		@Override
		protected void onPostExecute(Void result)
		{
			super.onPostExecute(result);
		}

		@Override
		protected void onCancelled()
		{
		}
	}

}