
var MAIN_URL = "https://linebroadcast.com/";
var API_BASE_URL = MAIN_URL;
var PARTNER = "openline/tools/customers/topspost/tp_tf_customer_v4.js";
var PRIVATE_CONFIG = "openline/tools/config/";
var PROMOTION = "openline/tools/promotion/";
var MY_SCRIPT = "openline/tools/myscripts/tfv3/";
var SCRIPT = "openline/tools/myscripts/tfv3/";
var DEVICE_ID1 = "";

MAIN_URL = "./";	//for local remark when use remote host
MY_SCRIPT = "myscripts/";	//for local remark when use remote host
SCRIPT = "scripts/";
PROMOTION = "fromhost/";
PRIVATE_CONFIG = "fromhost/";
PARTNER = "fromhost/tp_tf_customer_v4.js";

//var REQ_AUTH_URL = MAIN_URL + "tlmember/v2"+"{env}"+"/";
//var REQ_UNLOCK_URL = MAIN_URL + "deviceunlockreq/";

var IS_TF_MAX_SPEED_UNLIMIT = false;	//default from database

var CT_TF_ENV_ = "";

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
}

//b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
//b64EncodeUnicode('\n'); // "Cg=="

function b64DecodeUnicode(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}

//b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
//b64DecodeUnicode('Cg=='); // "\n"

/*
document.addEventListener("DOMContentLoaded",function(event){
	let head = document.querySelector("head");
	let loadJS = function(src){
		let jsLink = document.createElement("script");
		jsLink.src = src ;
		head.appendChild(jsLink);
	};
	console.log("First Javascript file loaded.");
	loadJS("nextFile.js");
});
*/

(async function() {
	//await const_init();
	var scriptNames = [
		"app-assets/vendors/jquery-3.5.1/jquery.js"
		//"app-assets/vendors/jquery-2.2.4/jquery.min.js"
		,"scripts/sweet.js"
		,"scripts/iziToast.js"
		,"scripts/client.min.js"
		,"app-assets/js/biri/biri.min.js"
		,"app-assets/rome.js"
		,"app-assets/dropdown/msdropdown/js/jquery.dd.js"
		,"app-assets/localStorageDB.js"
		,MAIN_URL+PRIVATE_CONFIG + "tp_tf_speed_config.js?version="+ (new Date().getTime())
		//,"scripts/tp_tf_gfunc.js"
		,MAIN_URL+SCRIPT + "tp_tf_gfunc.js?version="//+ (new Date().getTime())
		//,"myscripts/tp_tf_auth.js?version="+ (new Date().getTime())
		,MAIN_URL+MY_SCRIPT + "tp_tf_auth.js?version="//+ (new Date().getTime())
		,MAIN_URL+PROMOTION + "tp_tf_promotion.js?version="+ (new Date().getTime())
		,MAIN_URL+PARTNER + "?version="+ (new Date().getTime())
		,"scripts/tp_tf_gui.js"
		,"app-assets/jquery-resizable.js"
		,"app-assets/bootstrap.min.js"
		//,"myscripts/tp_tf_broadcast_fb_fanpage.js"
		,MAIN_URL+MY_SCRIPT + "tp_tf_broadcast_fb_fanpage.js?version="+ (new Date().getTime())
	];
	
	
	for (var i = 0; i < scriptNames.length; i++) {
		var res = await injectScript(scriptNames[i]);
		//console.log(scriptNames[i] + "->"+ res);
		/*
		var script = document.createElement('script');
		script.src = scriptNames[i];
		script.async = false; // This is required for synchronous execution
		document.head.appendChild(script);
		*/
	}
	
	
	
	function injectScript(src) {
		return new Promise((resolve, reject) => {
			const script = document.createElement('script');
			script.src = src;
			script.async = false; // This is required for synchronous execution
			script.addEventListener('load', resolve(true));
			script.addEventListener('error', e => resolve(false));
			//script.addEventListener('error', e => reject(e.error));
			document.head.appendChild(script);
		});
	}
  // jquery.js and example.js will be run in order and synchronously
  console.log("Loaded js script finished");

  	// // cleaned, 363b
  	// const ip = await new Promise((resolve, reject) => {
	// 	const conn = new RTCPeerConnection()
	// 	conn.createDataChannel('')
	// 	conn.createOffer(offer => conn.setLocalDescription(offer), reject)
	// 	conn.onicecandidate = ice => {
	// 	if (ice && ice.candidate && ice.candidate.candidate) {
	// 		resolve(i.candidate.candidate.split(' ')[4])
	// 		conn.close()
	// 	}
	// }
	// console.log("IP Address: "+ ip);
	// });
	const ip = await getLocalIP();
	console.log("IP Address: "+ ip);
})();

function getLocalIP() {
	return new Promise(function(resolve, reject) {
	  // NOTE: window.RTCPeerConnection is "not a constructor" in FF22/23
	  var RTCPeerConnection = /*window.RTCPeerConnection ||*/ window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
  
	  if (!RTCPeerConnection) {
		reject('Your browser does not support this API');
	  }
	  
	  var rtc = new RTCPeerConnection({iceServers:[]});
	  var addrs = {};
	  addrs["0.0.0.0"] = false;
	  
	  function grepSDP(sdp) {
		  var hosts = [];
		  var finalIP = '';
		  sdp.split('\r\n').forEach(function (line) { // c.f. http://tools.ietf.org/html/rfc4566#page-39
			  if (~line.indexOf("a=candidate")) {     // http://tools.ietf.org/html/rfc4566#section-5.13
				  var parts = line.split(' '),        // http://tools.ietf.org/html/rfc5245#section-15.1
					  addr = parts[4],
					  type = parts[7];
				  if (type === 'host') {
					  finalIP = addr;
				  }
			  } else if (~line.indexOf("c=")) {       // http://tools.ietf.org/html/rfc4566#section-5.7
				  var parts = line.split(' '),
					  addr = parts[2];
				  finalIP = addr;
			  }
		  });
		  return finalIP;
	  }
	  
	  if (1 || window.mozRTCPeerConnection) {      // FF [and now Chrome!] needs a channel/stream to proceed
		  rtc.createDataChannel('', {reliable:false});
	  };
	  
	  rtc.onicecandidate = function (evt) {
		  // convert the candidate to SDP so we can run it through our general parser
		  // see https://twitter.com/lancestout/status/525796175425720320 for details
		  if (evt.candidate) {
			var addr = grepSDP("a="+evt.candidate.candidate);
			resolve(addr);
		  }
	  };
	  rtc.createOffer(function (offerDesc) {
		  rtc.setLocalDescription(offerDesc);
	  }, function (e) { console.warn("offer failed", e); });
	});
}

function getClientID() {    //return numeric is success
	return new Promise(resolve =>{
		try {
			var client = new ClientJS(); // Create A New Client Object
			fingerprint = client.getFingerprint(); // Calculate Device/Browser Fingerprint
			if (fingerprint == null) {
				fingerprint = "";
			}
			if (fingerprint == "") {
				var ua = client.getBrowserData().ua;
				var canvasPrint = client.getCanvasPrint();
				fingerprint = client.getCustomFingerprint(ua, canvasPrint);
			}
			if (isNaN(fingerprint)){resolve("");}
			resolve(fingerprint);
		} catch (err) {
			resolve("");
		}
	});
}
function getVersion(){
	try{
		var manifestData = chrome.runtime.getManifest();
		//console.log(manifestData.version);
		//console.log(manifestData.default_locale);
		var fst_version_var	= CT_TF_APP_ID+"."+manifestData.version;	//in gfunc.js
		console.log(fst_version_var);
		return fst_version_var;
	}catch(e){}
	return "";
}
function initFingerprintJS() {
	// Initialize an agent at application startup.
	return new Promise(resolve =>{
		const fpPromise = FingerprintJS.load()

		// Get the visitor identifier when you need it.
		fpPromise
		  .then(fp => fp.get())
		  .then(result => {
			// This is the visitor identifier:
			const visitorId = result.visitorId
			resolve(visitorId);
		  });
	});
}
async function const_init_0() {
	DEVICE_ID1 = await getClientID();
	console.log(DEVICE_ID1);
	//DEVICE_ID2 = await biri();
	if(DEVICE_ID1==""){
		try{
			chrome.storage.local.get("information", function(info) {
				if(typeof info!=="undefined" && info!=null){
					if(typeof info.information!=="undefined" && info.information!=null){
						if(typeof info.information.device_id!=="undefined" && info.information.device_id!=null){
							if (info.information.device_id) {
								DEVICE_ID1=info.information.device_id.trim();
								console.log(DEVICE_ID1);
							}
						}
					}
				}
				//info && info.information && update_auth_info(info.information, func_call)
			});
		}catch(e){console.log(e);}
	}
}


function const_init() {
	return new Promise(async resolve =>{
		CT_TF_APP_VERSION = getVersion();
		
		console.log("const_init: ");
		
		let device_id = "";
		try{
			device_id = await initFingerprintJS();
		}catch(e){
			device_id = await getClientID();
		}
		DEVICE_ID1 = device_id;
		console.log("empty device: "+device_id);
		let information_device = {
			device_id:device_id
		}
		try{
			ldb.get('information_device', async function(info) {
				if(typeof info!=="undefined" && info!=null){
					if(typeof info.device_id!=="undefined" && info.device_id!=null){
						device_id = await info.device_id;
						console.log('device:'+DEVICE_ID1);
						if(device_id!=''){
							DEVICE_ID1 = device_id;
							console.log('device:'+DEVICE_ID1);
							information_device = {
								device_id:DEVICE_ID1
							}
							await ldb.set('information_device', information_device);
						}else{
							await ldb.set('information_device', information_device);
						}
						resolve(DEVICE_ID1);
					}else{
						await ldb.set('information_device', information_device);
						resolve(DEVICE_ID1);
					}
				}else{
					await ldb.set('information_device', information_device);
					resolve(DEVICE_ID1);
				}
			});
		}catch(e){
			console.log(e);
			await ldb.set('information_device', information_device);
			resolve(DEVICE_ID1);
		}

	});
}

