const puppeteer = require('puppeteer');

const appPermisions = `<AppPermissionRequests AllowAppOnlyPolicy="true" >
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
<AppPermissionRequest Scope="http://sharepoint/social/tenant" Right="FullControl" />
<AppPermissionRequest Scope="http://sharepoint/search" Right="QueryAsUserIgnoreAppPrincipal" />
<AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="FullControl" />
<AppPermissionRequest Scope="http://sharepoint/taxonomy" Right="Write" />
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="FullControl" />
</AppPermissionRequests>`;



const config = {
    url: process.argv[2], //"https://testspcool.sharepoint.com/sites/testinstallation2",
    adminUrl:process.argv[3], //"https://testspcool-admin.sharepoint.com",
    clientId:process.argv[4], //"290359ab-3359-42cc-908a-41e2c2075f9a",
    username: process.argv[5], //"test@testspcool.onmicrosoft.com",
    password: process.argv[6], //"",
    waittime: 2000,
	waittimelong: 5000
};

const elements = {
    login: 'input[type="email"]',
    submit: 'input[type="submit"]',
    pass: 'input[name="passwd"]',
    appIdTextBox:'input[id="ctl00_ctl00_PlaceHolderContentArea_PlaceHolderMain_IdTitleEditableInputFormSection_ctl01_TxtAppId"]',
    appIdSearchButton:'input[id="ctl00_ctl00_PlaceHolderContentArea_PlaceHolderMain_IdTitleEditableInputFormSection_ctl01_BtnLookup"]',
    permissionsIdTextBox:'textarea[id="ctl00_ctl00_PlaceHolderContentArea_PlaceHolderMain_TitleDescSection_ctl01_TxtPerm"]',
    createAppButton:'input[id="ctl00_ctl00_PlaceHolderContentArea_PlaceHolderMain_ctl01_RptControls_BtnCreate"]',
    trustAppButton:'input[id="ctl00_ctl00_PlaceHolderContentArea_PlaceHolderMain_BtnAllow"]',
    redirectUrlTextBox: 'input[id="ctl00_ctl00_PlaceHolderContentArea_PlaceHolderMain_IdTitleEditableInputFormSection_ctl04_TxtRedirectUrl"]',
    adminSite: 'ul[id="Ribbon.TenantAdmin.SiteCollections"]',
	adminSiteModern: 'div[data-automation-id="app-nav-root"]',
	adminSiteModernV2: 'div[data-automation-id="navItems"]'
};

const login = async (page) => {
    console.log(`navigating to ${config.url}`);
    let notFound = true;
	while (notFound) {
		try {
			await page.goto(config.url,{waitUntil:'domcontentloaded'});
			await page.waitForSelector(elements.login);
			await page.waitFor(config.waittimelong);
			notFound = false;
		} catch (error) {
			console.log(`Pageload failed. Retrying...`);
			await page.waitFor(config.waittimelong);
		}
	}

    console.log(`logging in with user ${config.username}`);
    await page.type(elements.login, config.username);
    await page.click(elements.submit);
    await page.waitFor(config.waittime);

    //console.log(`loggin in with password ${config.password}`);
    await page.type(elements.pass, config.password);
    await page.click(elements.submit);
    await page.waitFor(config.waittime);

    console.log(`-- logged in --`);
}

const useappinv = async(page) =>{
	console.log(`give permissions to the app`);
	let notFound = true;
	while (notFound) {
		try {
			console.log(`Contacting ${config.adminUrl}/_layouts/15/appinv.aspx`);
			await page.goto(`${config.adminUrl}/_layouts/15/appinv.aspx`,{waitUntil:'domcontentloaded'});
			await page.waitForSelector(elements.appIdTextBox);
			await page.waitForSelector(elements.appIdSearchButton);
			await page.waitFor(config.waittime);
			console.log(`Searching for the SharePoint App`);
			await page.type(elements.appIdTextBox, config.clientId);
			const navigationPromise = page.waitForNavigation();
			await page.click(elements.appIdSearchButton);
			await navigationPromise; // The navigationPromise resolves after navigation has finished
			const redirectUrlTextBox = elements.redirectUrlTextBox
			await page.waitForFunction(
				redirectUrlTextBox => document.querySelector(redirectUrlTextBox).getAttribute("Value").includes("https"),
				{},
				redirectUrlTextBox
			);
			notFound = false;
		} catch (error) {
			console.log(`Search for the SharePoint App failed`);
			console.log(`-- Retry --`);
			await page.waitFor(config.waittimelong);
		}
	}
	console.log(`Adding permissions to the SharePoint App`);
    await page.type(elements.permissionsIdTextBox, appPermisions);
    await page.click(elements.createAppButton);
    await page.waitForSelector(elements.trustAppButton);
	console.log(`Setting App as a trusted app`);
    await page.click(elements.trustAppButton);
    await Promise.race([
		page.waitForSelector(elements.adminSite),
		page.waitForSelector(elements.adminSiteModern),
		page.waitForSelector(elements.adminSiteModernV2)
	]);
}

puppeteer.launch({headless:true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }).then(async browser => {

    console.log("-- starting --");
   
    // open browser
    const page = await browser.newPage();
	await page.setDefaultTimeout(0);
	await page.setDefaultNavigationTimeout(0);
    await page.setViewport({
        width: 1920,
        height: 1080
    });
    // login
    await login(page);
    // trust the app
    await useappinv(page);
    console.log("-- done --");
    // close the browser
    await browser.close();

});