import { exec } from "child_process";
import axios from "axios";
import { debug } from ".";
let tor_axios = require('tor-axios');

export class Links {

	tor = tor_axios.torSetup({
		ip: 'localhost',
		port: 9050,
		controlPort: '9051',
		controlPassword: 'giraffe'
	})

	inst = axios.create({
		httpAgent: this.tor.httpAgent(),
		httpsAgent: this.tor.httpsAgent()
	});

	parse_cookie(cookies: string[] | undefined) {
		if(!cookies) return "";
		let cookie_list: string[] = [];
		cookies.forEach(c => {
			cookie_list.push(c.split(";")[0]);
		});
		return cookie_list.join("; ");
	}

	regex_escape(string: string) {
		return string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
	}

	regex_parse(regex: RegExp, text: string, group: number): string | undefined {
		let match = regex.exec(text);
		if(!match) return;
		return match![group] ? match![group] : undefined;
	}

	async direct_link(id: string): Promise<string | undefined> {

		let download_link = "https://uloz.to/download-dialog/free/download?fileSlug="+id;
		let redirect = await this.inst.get(download_link, {maxRedirects: 0, validateStatus: null});
		if(redirect.status !== 302) throw new Error(`Status code: ${redirect.status}`);
		this.tor.torNewSession();
		if(redirect.headers.location && redirect.headers.location.startsWith("https://download.uloz.to"))
			return redirect.headers.location;

	}

	async captcha_link(id: string): Promise<string | undefined> {

		let download_link = "https://uloz.to/download-dialog/free/download?fileSlug="+id;
		let captcha_page = await this.inst.get(download_link, {maxRedirects: 0, validateStatus: null});

		if(captcha_page.status !== 200) throw new Error(`Status code: ${captcha_page.status}`);
		let cookies = this.parse_cookie(captcha_page.headers["set-cookie"]);

		let url = this.regex_parse(/<img class="xapca-image" src="([^"]*)" alt="">/gm, captcha_page.data, 1);
		if(!url) return undefined;
		let captcha_image = new URL(url, "https://localhost").href;
		if(debug) console.info(`${id} | captcha image: ${captcha_image}`);

		let captcha = await this.captcha(captcha_image);
		if(debug) console.info(`${id} | captcha code: ${captcha}`);

		let form = new URLSearchParams();

		["_token_", "timestamp", "salt", "hash", "captcha_type", "_do"].forEach(name => {
			let regex = "name=\""+this.regex_escape(name)+"\" value=\"([^\"]*)\"";
			let resp = this.regex_parse(new RegExp(regex), captcha_page.data, 1);
			if(resp) form.append(name, resp);
		});

		form.append("captcha_value", captcha);

		let result = await this.inst({
			method: "POST",
			url: download_link,
			data: form,
			headers: {
				"Accept-Encoding": "gzip",
				"X-Requested-With": "XMLHttpRequest",
				"User-Agent": "Go-http-client/1.1",
				"Cookie": cookies
			},
			validateStatus: null
		});
		this.tor.torNewSession();
		return result.data.slowDownloadLink;

	}

	async captcha(url: string): Promise<string> {
		return new Promise((resolve) => {
			exec("python3 captcha.py "+url, (e, o) => {
				resolve(o);
			});
		});
	}

}