# request.js

    const https = require("https");
    const querystring = require("querystring");
    const zlib = require("zlib");

    const API_BASE_URL = "api.showmyhomework.co.uk";
    const SATCHELONE = "https://www.satchelone.com"

    /**
     * @typedef RequestOptions
     * @property {String} [host] The base hostname for the request.
     * @property {Number} [port] The port of the request.
     * @property {Object} [query] The querystring options for the request.
     * @property {Object} [body] The post data body of the request.
     * @property {Object} [headers] The headers for the request.
     * @property {String} [referer] The referer path for the request.
     * @property {Object} [payload] The JSON payload for the request.
     */

    /**
     *
     * @param {String} method The method for the request.
     * @param {String} path The path of the request.
     * @param {RequestOptions} options The options for the request.
     */
    function makeRequest(method, path, options = {}) {
    	return new Promise((resolve, reject) => {
    		const request_options = {};

    		request_options.method = method;
    		request_options.host = options.host || API_BASE_URL;
    		request_options.path = path;
    		request_options.port = options.port || 443;

    		if (options.query) {
    			for (let i in options.query) {
    				if (Array.isArray(options.query[i])) {
    					options.query[i + "[]"] = options.query[i];
    					delete options.query[i];
    				}
    			}

    			request_options.path += "?" + querystring.stringify(options.query);
    		}

    		const post_data = querystring.stringify(options.body || {});

    		request_options.headers = {
    			"accept": "application/smhw.v3+json",
    			"accept-encoding": "gzip, deflate, br",
    			"accept-language": "en-GB,en;q=0.9,es-GB;q=0.8,es;q=0.7,en-US;q=0.6",
    			"origin": SATCHELONE,
    			"referer": SATCHELONE + (options.referer || "/login"),
    			"sec-fetch-dest": "empty",
    			"sec-fetch-mode": "cors",
    			"sec-fetch-site": "cross-site",
    			"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Safari/537.36",

    			...options.headers
    		}

    		if (options.body) {
    			request_options.headers["Content-Type"] = "application/x-www-form-urlencoded";
    			request_options.headers["Content-Length"] = Buffer.byteLength(post_data);
    		}

    		if (options.payload) {
    			request_options.headers["Content-Type"] = "application/json; charset=UTF-8";
    			request_options.headers["Content-Length"] = Buffer.byteLength(JSON.stringify(options.payload));
    		}

    		const post_req = https.request(request_options, res => {
    			let chunks = [];

    			if (res.headers["content-encoding"] === "gzip") {
    				var unzip = res.pipe(zlib.createGunzip());

    				unzip.on("data", data => {
    					chunks.push(data);
    				});

    				unzip.on("end", () => {
    					const buf = chunks.join("");

    					try {
    						resolve(JSON.parse(buf));
    					} catch {
    						resolve(buf);
    					}
    				});
    			} else {
    				res.on("data", data => {
    					chunks.push(data);
    				});

    				res.on("end", () => {
    					const buf = chunks.join("");

    					try {
    						resolve(JSON.parse(buf));
    					} catch {
    						resolve(buf);
    					}
    				});
    			}
    		});

    		if (options.body)
    			post_req.write(post_data);

    		if (options.payload)
    			post_req.write(JSON.stringify(options.payload));

    		post_req.end();
    	});
    }

    module.exports = {
    	make: makeRequest
    }