const puppeteer = require('puppeteer');
const fs = require('fs')
var argv = require('minimist')(process.argv.slice(2));
const timers = require('timers-promises');

(async () => {
	if(argv.hasOwnProperty('u')) {
		var webpageurl = argv['u'];
		try {
			const url = new URL(webpageurl);
			var hostname = url.hostname;
			var pa = {headless:true};
			//var lo = {};
			if(argv.hasOwnProperty('nosb')) 
				pa = {headless:true, args: ['--no-sandbox', '--disable-setuid-sandbox']};
			//if(argv.hasOwnProperty('wunwi')) 
			//	lo = {"waitUntil" : "networkidle0"};
			const browser = await puppeteer.launch(pa);
			const page = await browser.newPage();
			try {
				await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36');
				await page.setViewport({
				  width: 1024,
				  height: 768,
				  deviceScaleFactor: 1
				});
				if(argv.hasOwnProperty('nojs')) 
					await page.setJavaScriptEnabled(false);
				await page.setDefaultNavigationTimeout(30000);
				
				await page.goto(webpageurl, {'timeout': 10000, 'waitUntil':'load'});
				await waitTillHTMLRendered(page, 10000)
				
				//await page.goto(webpageurl, lo);
				if(argv.hasOwnProperty('ac')) {
					const client = await page.target().createCDPSession();
					var cookies = (await client.send('Network.getAllCookies')).cookies;
				}
				else
					var cookies = await page.cookies();
				
				if (!fs.existsSync('cookies')){
					fs.mkdirSync('cookies');
				}
				if (!fs.existsSync('webshots')){
					fs.mkdirSync('webshots');
				}
				console.log(cookies);
				fs.writeFileSync('cookies/' + hostname + '.json', JSON.stringify(cookies));
				
				await page.screenshot({ path: 'webshots/' + hostname + '.jpg' });
			}
			catch(error) {
				throw Error(error);
			}
			await page.close(); 
			await browser.close();
		}
		catch(error) {
			console.log(error);
			process.exit(1);
		}
	}
})();


async function waitTillHTMLRendered(page, timeout = 30000) {
	const checkDurationMsecs = 1000;
	const maxChecks = timeout / checkDurationMsecs;
	let lastHTMLSize = 0;
	let checkCounts = 1;
	let countStableSizeIterations = 0;
	const minStableSizeIterations = 3;

	while(checkCounts++ <= maxChecks) {
		let html = await page.content();
		let currentHTMLSize = html.length; 

		await page.mouse.move(100+Math.floor(Math.random() * 10), 40+Math.floor(Math.random() * 10));

		let bodyHTMLSize = await page.evaluate(() => document.body.innerHTML.length);

		//console.log('last: ', lastHTMLSize, ' <> curr: ', currentHTMLSize, " body html size: ", bodyHTMLSize);

		if(lastHTMLSize != 0 && currentHTMLSize == lastHTMLSize) 
			countStableSizeIterations++;
		else 
			countStableSizeIterations = 0; //reset the counter

		if(countStableSizeIterations >= minStableSizeIterations) {
			//console.log("Page rendered fully..");
			break;
		}

		lastHTMLSize = currentHTMLSize;
//		await page.waitForTimeout(checkDurationMsecs);
		await timers.setTimeout(checkDurationMsecs);
	}  
};
