const puppeteer = require('puppeteer-core');
const request = require('request');

const url = process.argv[2];
playVideo(url).catch(error => {
  console.error('Error:', error);
});

async function playVideo(url) {
  const browser = await puppeteer.launch({
    executablePath: './chrome-linux/chrome',
    headless: true,
    args: [
      '--no-sandbox',
      '--disable-gpu',
      '--ignore-certificate-errors',
    ],
  });

  const page = await browser.newPage();
  const retryErrorConfigUrls = [];

  try {
    // Step 1: Get firstResult before loading newUrl
    let firstResult = 'Null';
    await page.goto(url, {
      timeout: 60000,
      waitUntil: 'networkidle0',
    });

    const firstElement = await page.$('b.api-key-text');
    if (firstElement) {
      firstResult = await page.evaluate(element => element.textContent, firstElement);
    }

    // Step 2: Get the current page URL
    const currentUrl = page.url();

    // Step 3: Create a new URL by replacing 'UI/Dashboard' with 'api/v2.0/indexers?configured=true'
    const newUrl = currentUrl.replace('UI/Dashboard', 'api/v2.0/indexers?configured=true');

    // Step 4: Load the new URL and get its response as pretty JSON
    await page.goto(newUrl, {
      timeout: 60000,
      waitUntil: 'networkidle0',
    });

    // Step 5: Get cookies from the page
    const cookies = await page.cookies();

    const response = await page.evaluate(() => {
      return JSON.parse(document.body.innerText);
    });

    // Step 6: Filter the array to keep only elements where the value of the 'type' key contains 'private' and 'configured' is true (case-insensitive)
    const privateItems = response.filter(item => {
      const isPrivate = item.type.toLowerCase().includes('private');
      const isConfigured = String(item.configured).toLowerCase() === 'true';
      return isPrivate && isConfigured;
    });

    if (privateItems.length > 0) {
      console.log(`\nTorznab key: ${firstResult}\n`); // Print the Torznab key only if privateItems is not zero
    } else {
      process.exit(0); // Exit the script with zero exit code as there are no private items to process
    }

    // Step 7: Modify each element to keep only the 'id' and construct the 'config_url'
    const finalResult = privateItems.map(item => {
      const { id } = item;
      const config_url = currentUrl.replace('UI/Dashboard', `api/v2.0/indexers/${id}/config`);
      return { id, config_url };
    });

    // Step 8: Process each config_url using request module with cookies and timeout
    for (const item of finalResult) {
      try {
        const configResponse = await getConfigResponseWithCookies(item.config_url, cookies);

        // Step 9: Parsing and filtering the response
        const filteredElements = configResponse.filter(element => {
          return (
            element.type === 'inputstring' &&
            typeof element.value !== 'boolean' &&
            element.value !== null
          );
        });

        const groupedValues = filteredElements.map(element => element.value).join(' | ');

        const prefixedGroupedValues = item.id + ' | ' + groupedValues;
        console.log(prefixedGroupedValues);
      } catch (error) {
        console.log(`##${item.id} | ${item.config_url} | ${error.message}`); // Print errored URLs to stdout
        retryErrorConfigUrls.push(item.config_url);
      }
    }

    // Step 10: Retry error config_urls with increasing timeout
    let retryTimeout = 3000; // Initial retry timeout is 15 seconds
    while (retryErrorConfigUrls.length > 0 && retryTimeout <= 30000) {
      const retryResults = [];
      for (const configUrl of retryErrorConfigUrls) {
        try {
          const configResponse = await getConfigResponseWithCookies(configUrl, cookies, retryTimeout);
          retryResults.push({ configUrl, response: configResponse });
        } catch (error) {
          console.log(`##Retry ${retryTimeout}ms | ${configUrl}|${error.message}`); // Print errored URLs to stdout
        }
      }

      // Remove successfully processed config_urls from retryErrorConfigUrls
      retryErrorConfigUrls.length = 0;
      for (const retryResult of retryResults) {
        const configUrl = retryResult.configUrl;
        const configResponse = retryResult.response;
        if (!configResponse.error) {
          // Step 11: Parsing and filtering the response (same as in Step 9)
          const filteredElements = configResponse.filter(element => {
            return (
              element.type === 'inputstring' &&
              typeof element.value !== 'boolean' &&
              element.value !== null
            );
          });

          const groupedValues = filteredElements.map(element => element.value).join(' | ');

          const prefixedGroupedValues = configUrl + ' | ' + groupedValues;
          console.log(prefixedGroupedValues);
        } else {
          // Config url still encounters an error, add it back to retryErrorConfigUrls
          retryErrorConfigUrls.push(configUrl);
        }
      }

      retryTimeout *= 2; // Double the retry timeout for the next retry
    }

  } catch (error) {
    console.error('Error:', error);
  } finally {
    await browser.close();
  }

  process.exit(0); // Exit the script with zero exit code after completing the process
}

function getConfigResponseWithCookies(url, cookies, timeout = 10000) {
  return new Promise((resolve, reject) => {
    const requestTimeout = setTimeout(() => {
      reject(new Error('HTTP request timeout'));
    }, timeout);

    request(
      {
        url,
        headers: {
          Cookie: cookies.map(cookie => `${cookie.name}=${cookie.value}`).join('; '),
        },
      },
      (error, response, body) => {
        clearTimeout(requestTimeout); // Clear the request timeout when the request is completed
        if (error) {
          reject(error);
        } else {
          resolve(JSON.parse(body));
        }
      }
    );
  });
}
Convert to golang based script which uses go-rod which is equivalent to puppeteer-core