package hh.dejsem.fm;

import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;

import java.io.File;
import java.util.HashMap;

import hh.dejsem.K;
import hh.dejsem.R;
import hh.dejsem.net.ExposeStream;
import hh.dejsem.net.ExposeFile;
import hh.dejsem.net.SrvCmd;
import hh.lib.D;
import hh.lib.DF;

/**
 * responds to intentions to send data to server
 */
public class UploadFrag extends DF implements View.OnClickListener {

	String TITLETEXT = "share";

	public static UploadFrag instantiate(D d, Intent intent) {
		UploadFrag uf = new UploadFrag();
		uf.d = d.klon(uf);
		uf.intent = intent;
		return uf;
	}

	static HashMap<Integer, String> flagNames = new HashMap<>();
	static {
		flagNames.put(Intent.FLAG_FROM_BACKGROUND, "FLAG_FROM_BACKGROUND");
		flagNames.put(Intent.FLAG_DEBUG_LOG_RESOLUTION, "FLAG_DEBUG_LOG_RESOLUTION");
		flagNames.put(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES, "FLAG_EXCLUDE_STOPPED_PACKAGES");
		flagNames.put(Intent.FLAG_INCLUDE_STOPPED_PACKAGES, "FLAG_INCLUDE_STOPPED_PACKAGES");
		flagNames.put(Intent.FLAG_ACTIVITY_MATCH_EXTERNAL, "FLAG_ACTIVITY_MATCH_EXTERNAL");
		flagNames.put(Intent.FLAG_ACTIVITY_NO_HISTORY, "FLAG_ACTIVITY_NO_HISTORY");
		flagNames.put(Intent.FLAG_ACTIVITY_SINGLE_TOP, "FLAG_ACTIVITY_SINGLE_TOP");
		flagNames.put(Intent.FLAG_ACTIVITY_NEW_TASK, "FLAG_ACTIVITY_NEW_TASK");
		flagNames.put(Intent.FLAG_ACTIVITY_MULTIPLE_TASK, "FLAG_ACTIVITY_MULTIPLE_TASK");
		flagNames.put(Intent.FLAG_ACTIVITY_CLEAR_TOP, "FLAG_ACTIVITY_CLEAR_TOP");
		flagNames.put(Intent.FLAG_ACTIVITY_FORWARD_RESULT, "FLAG_ACTIVITY_FORWARD_RESULT");
		flagNames.put(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP, "FLAG_ACTIVITY_PREVIOUS_IS_TOP");
		flagNames.put(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, "FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS");
		flagNames.put(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT, "FLAG_ACTIVITY_BROUGHT_TO_FRONT");
		flagNames.put(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, "FLAG_ACTIVITY_RESET_TASK_IF_NEEDED");
		flagNames.put(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY, "FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY");
		flagNames.put(Intent.FLAG_ACTIVITY_NEW_DOCUMENT, "FLAG_ACTIVITY_NEW_DOCUMENT");
		flagNames.put(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, "FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET");
		flagNames.put(Intent.FLAG_ACTIVITY_NO_USER_ACTION, "FLAG_ACTIVITY_NO_USER_ACTION");
		flagNames.put(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT, "FLAG_ACTIVITY_REORDER_TO_FRONT");
		flagNames.put(Intent.FLAG_ACTIVITY_NO_ANIMATION, "FLAG_ACTIVITY_NO_ANIMATION");
		flagNames.put(Intent.FLAG_ACTIVITY_CLEAR_TASK, "FLAG_ACTIVITY_CLEAR_TASK");
		flagNames.put(Intent.FLAG_ACTIVITY_TASK_ON_HOME, "FLAG_ACTIVITY_TASK_ON_HOME");
		flagNames.put(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS, "FLAG_ACTIVITY_RETAIN_IN_RECENTS");
		flagNames.put(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT, "FLAG_ACTIVITY_LAUNCH_ADJACENT");
		flagNames.put(Intent.FLAG_RECEIVER_REGISTERED_ONLY, "FLAG_RECEIVER_REGISTERED_ONLY");
		flagNames.put(Intent.FLAG_RECEIVER_REPLACE_PENDING, "FLAG_RECEIVER_REPLACE_PENDING");
		flagNames.put(Intent.FLAG_RECEIVER_FOREGROUND, "FLAG_RECEIVER_FOREGROUND");
		flagNames.put(Intent.FLAG_RECEIVER_NO_ABORT, "FLAG_RECEIVER_NO_ABORT");
		flagNames.put(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS, "FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS");
	}

	Intent intent;
	View view = null;
	Button analyze, expose;
	/*View.OnLongClickListener longClickToUpload = new View.OnLongClickListener() {
		@Override 
		public boolean onLongClick(View v) { return handleFileUpload(); }
	};*/

	/*@Override
	public void onCreate(Bundle b) {
		super.onCreate(b);
		setRetainInstance(true);
	}*/
	
	@Override 
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		super.onCreateView(inflater, container, savedInstanceState);
		setRetainInstance(true);
		if(view == null) {
			view = inflater.inflate(R.layout.upload_panel, null);
			d.sc = (ScrollView) view.findViewById(R.id.sc);
			d.tv = (TextView) view.findViewById(R.id.tv);
			d.tv.setText("");
			analyze = view.findViewById(R.id.analyze);
			analyze.setOnClickListener(this);
			if(intent.hasExtra(Intent.EXTRA_STREAM)) {
				expose = view.findViewById(R.id.expose);
				expose.setVisibility(View.VISIBLE);
				expose.setOnClickListener(this);
			}
			else d.tv.append("\nshared object has no data stream");
		}
		return view;
	}

	/*@Override
	public void onActivityCreated(Bundle b) {
		super.onActivityCreated(b);
	}*/

	@Override
	public void onClick(View v) {
		if(v.getId() == R.id.analyze) analyze();
		else if(v.getId() == R.id.expose) expose();
	}

	void analyze() {
		analyze.setVisibility(View.GONE);
		String flags = "";
		for(int i=32; i>=0; i--) {
			int flag = 1 << i;
			if(flagNames.containsKey(flag) && (intent.getFlags() & flag) != 0)
				flags += String.format("\n\t%08x, %s", flag, flagNames.get(flag));
		}
		String keys = "";
		if(intent.getExtras() != null) for(String key: intent.getExtras().keySet()) keys += key + " ";
		if(d.ll(4)) {
			d.l("toUri()=" + intent.toUri(0));
			d.l("getAction()=" + intent.getAction());
			d.l("getData()=" + intent.getData());
			d.l("getType()=" + intent.getType());
			d.l("Extras keys=" + keys);
		}
		d.tv.append("\naction=" + intent.getAction());
		d.tv.append(String.format("\nflags=%x", intent.getFlags()));
		if(flags.length() > 0) d.tv.append(flags);
		d.tv.append("\ndescribeContents()=" + intent.describeContents());
		d.tv.append("\ngetAction()=" + intent.getAction());
		d.tv.append("\ngetCategories()=" + intent.getCategories());
		d.tv.append("\ngetComponent()=" + intent.getComponent());
		d.tv.append("\ngetData()=" + intent.getDataString());
		d.tv.append("\ngetDataString()=" + intent.getDataString());
		d.tv.append("\ngetPackage()=" + intent.getPackage());
		d.tv.append("\ngetScheme()=" + intent.getScheme());
		d.tv.append("\ngetType()=" + intent.getType());
		d.tv.append("\nhasFileDescriptors()=" + intent.hasFileDescriptors());
		if(intent.getCategories() != null) {
			d.tv.append("\ncategores:");
			for(String s: intent.getCategories()) d.tv.append("\n  " + s); }
		d.tv.append("\ngetExtras()=" + intent.getExtras());
		if(intent.getExtras() != null) d.tv.append("\ndescribeContents()=" + intent.getExtras().describeContents());
		d.tv.append("\nExtras keys=" + keys);
		d.tv.append("\nhasExtra[EXTRA_TEXT]=" + intent.hasExtra(Intent.EXTRA_TEXT));
		d.tv.append("\nEXTRA_TEXT=" + intent.getStringExtra(Intent.EXTRA_TEXT));
		d.tv.append("\nhasExtra[EXTRA_STREAM]=" + intent.hasExtra(Intent.EXTRA_STREAM));
		d.tv.append("\nEXTRA_STREAM=" + (Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM));
		if(intent.getExtras() != null) {
			Bundle b = intent.getExtras();
			if(b.containsKey(K.FN_KEY)) d.tv.append("\nfile=" + b.getString(K.FN_KEY));
			Uri uri = b.getParcelable(Intent.EXTRA_STREAM);
			if(uri != null) {
				if(d.ll(4)) d.l("EXTRA_STREAM=" + uri);
				d.tv.append("\nstream URI:");
				d.tv.append("\n\ttoString()=" + uri.toString());
				d.tv.append("\n\tisAbsolute()=" + uri.isAbsolute());
				d.tv.append("\n\tisHierarchical()=" + uri.isHierarchical());
				d.tv.append("\n\tgetScheme()=" + uri.getScheme());
				d.tv.append("\n\tgetAuthority()=" + uri.getAuthority());
				d.tv.append("\n\tgetHost()=" + uri.getHost());
				d.tv.append("\n\tgetFragment()=" + uri.getFragment());
				d.tv.append("\n\tgetPath()=" + uri.getPath());
				}
			}
		}

	void expose() {
		expose.setVisibility(View.GONE);
		Uri uri = intent.getExtras().getParcelable(Intent.EXTRA_STREAM);
		if(uri.getScheme().equals("file")) handleFileUpload(uri);
		else handleStreamUpload(uri);
	}

	boolean handleFileUpload(Uri uri) {
		try {
			d.l(4, "handleFileUpload, START");
			int port = (Integer)SrvCmd.LONGTASK.exec(d, null);
			K.cmdConnClose(d);
			if(port == 0) throw new Exception("all server ports are busy", null);
			Bundle taskParms = new Bundle();
			taskParms.putInt(K.PORT_KEY, port);
			String[] selection = new String[] { new File(uri.toString()).getPath() };
			taskParms.putStringArray(K.FILES_FROM_KEY, selection);
			taskParms.putString(K.FILE_TO_KEY, "");
			EntitySize es = FileList.reckon(selection);
			TaskProgress taskProgress = new TaskProgress(d, es);
			K.prepTransferOverview(d);
			FragFM.sweepOutNetCmd(d);
			NetTaskRef netTaskRef = new NetTaskRef(d, taskParms, es);
			d.l(4, String.format("netTaskRef=%s", netTaskRef));
            new ExposeFile(d, netTaskRef).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
			d.l(4, "handleFileExpose, END, upload handed over to background");
			return true;
		}
		catch(Exception e) { 
			d.abendMsg(e);
			return false;
		}
	}

	boolean handleStreamUpload(Uri uri) {
			d.l(4, "handleStreamUpload, START");
			Bundle taskParms = new Bundle();
			String mimeType = intent.getType();
			taskParms.putString(K.MIME_TYPE_KEY, mimeType != null ? mimeType : "");
			taskParms.putParcelable(K.STREAM_KEY, intent.getExtras().getParcelable(Intent.EXTRA_STREAM));
		try {
			ContentResolver cr = d.getContext().getContentResolver();
			ContentProviderClient cc = cr.acquireContentProviderClient(uri);
			if(cc == null) throw new Exception("data stream has no content provider");
			Long size = cc.openAssetFile(uri, "r").getLength();
			EntitySize es = new EntitySize(size, 1, 0);
			TaskProgress taskProgress = new TaskProgress(d, es);
			int port = (Integer)SrvCmd.LONGTASK.exec(d, null);
			K.cmdConnClose(d);
			if(port == 0) throw new Exception("all server ports are busy", null);
			taskParms.putInt(K.PORT_KEY, port);
			K.prepTransferOverview(d);
			FragFM.sweepOutNetCmd(d);
			NetTaskRef netTaskRef = new NetTaskRef(d, taskParms, es);
			d.l(4, String.format("netTaskRef=%s", netTaskRef));
            new ExposeStream(d, netTaskRef).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
			d.l(4, "handleStreamExpose, END, upload handed over to background");
			return true;
		}
		catch(Exception e) {
			d.abendMsg(e);
			return false;
		}
	}
}
