export function protocolInit(): void {
    // get all args except `hidden` as it'd mean the app would not get focused
    // XXX: passing args to protocol handlers only works on Windows, so unpackaged deep-linking
    // --profile/--profile-dir are passed via the SEARCH_PARAM var in the callback url
    const args = process.argv.slice(1).filter(arg => arg !== "--hidden" && arg !== "-hidden");
    if (app.isPackaged) {
        app.setAsDefaultProtocolClient('element', process.execPath, args);
    } else if (process.platform === 'win32') { // on Mac/Linux this would just cause the electron binary to open
        // special handler for running without being packaged, e.g `electron .` by passing our app path to electron
        app.setAsDefaultProtocolClient('element', process.execPath, [app.getAppPath(), ...args]);
    }

    if (process.platform === 'darwin') {
        // Protocol handler for macos
        app.on('open-url', function(ev, url) {
            ev.preventDefault();
            processUrl(url);
        });
    } else {
        // Protocol handler for win32/Linux
        app.on('second-instance', (ev, commandLine) => {
            const url = commandLine[commandLine.length - 1];
            if (!url.startsWith(PROTOCOL)) return;
            processUrl(url);
        });
    }
}


function generate(
	target: any,
	hierarchies: SetupPropParam[],
	forceOverride?: boolean
) {
	let current = target;
	hierarchies.forEach(info => {
		const descriptor = normalizeDescriptor(info);
		const {value, type, create, override, created, skipped, got} = descriptor;

		const name = getNonEmptyPropName(current, descriptor);
		if (forceOverride || override || !current[name] || typeof current[name] !== 'object') {
			const obj = value ? value :
				type ? new type() :
					create ? create.call(current, current, name) :
						{};
			current[name] = obj;

			if (created) {
				created.call(current, current, name, obj);
			}
		} else {
			if (skipped) {
				skipped.call(current, current, name, current[name]);
			}
		}

		const parent = current;
		current = current[name];
		if (got) {
			got.call(parent, parent, name, current);
		}
	});

	return current;
}


async function f(v) {
    if (v == 3) {
        return;
    }

    stages.push(`f>${v}`);

    await "X";

    f(v + 1);

    stages.push(`f<${v}`);
}


function processUrl(url: string): void {
    if (!global.mainWindow) return;
    console.log("Handling link: ", url);
    global.mainWindow.loadURL(url.replace(PROTOCOL, "vector://"));
}


  constructor(line: string, lineNumber: number) {
    super(`Unsupported type of line: [${lineNumber}]"${line}"`);
    this.line = line;
    this.lineNumber = lineNumber;
  }


var getDefaultObject = function () {
  return {
    nested: {
      thing: {
        foo: 'bar'
      },
      is: {
        cool: true
      }
    },
    dataUndefined: undefined,
    dataDate: now,
    dataNumber: 42,
    dataString: 'foo',
    dataNull: null,
    dataBoolean: true
  };
};


export function setByKeyPath(obj, keyPath, value) {
    if (!obj || keyPath === undefined) return;
    if ('isFrozen' in Object && Object.isFrozen(obj)) return;
    if (typeof keyPath !== 'string' && 'length' in keyPath) {
        assert(typeof value !== 'string' && 'length' in value);
        for (var i = 0, l = keyPath.length; i < l; ++i) {
            setByKeyPath(obj, keyPath[i], value[i]);
        }
    } else {
        var period = keyPath.indexOf('.');
        if (period !== -1) {
            var currentKeyPath = keyPath.substr(0, period);
            var remainingKeyPath = keyPath.substr(period + 1);
            if (remainingKeyPath === "")
                if (value === undefined) {
                    if (isArray(obj) && !isNaN(parseInt(currentKeyPath))) obj.splice(currentKeyPath, 1);
                    else delete obj[currentKeyPath];
                } else obj[currentKeyPath] = value;
            else {
                var innerObj = obj[currentKeyPath];
                if (!innerObj) innerObj = (obj[currentKeyPath] = {});
                setByKeyPath(innerObj, remainingKeyPath, value);
            }
        } else {
            if (value === undefined) {
                if (isArray(obj) && !isNaN(parseInt(keyPath))) obj.splice(keyPath, 1);
                else delete obj[keyPath];
            } else obj[keyPath] = value;
        }
    }
}


export function getProfileFromDeeplink(args): string | undefined {
    // check if we are passed a profile in the SSO callback url
    const deeplinkUrl = args.find(arg => arg.startsWith('element://'));
    if (deeplinkUrl && deeplinkUrl.includes(SEARCH_PARAM)) {
        const parsedUrl = new URL(deeplinkUrl);
        if (parsedUrl.protocol === 'element:') {
            const ssoID = parsedUrl.searchParams.get(SEARCH_PARAM);
            const store = readStore();
            console.log("Forwarding to profile: ", store[ssoID]);
            return store[ssoID];
        }
    }
}