import { getEnvAwareBrowserInstance } from './smartpuppeteer.classes.smartpuppeteer.js';
import * as plugins from './smartpuppeteer.plugins.js';

export class IncognitoBrowser {
  public status: 'started' | 'stopped' = 'stopped';
  public browser!: plugins.puppeteer.Browser;

  constructor() {}

  /**
   * Starts the IncognitoBrowser instance.
   * It launches the browser using environment-aware options and sets up a listener
   * to automatically re-launch if the browser disconnects while the status is 'started'.
   */
  public async start(): Promise<void> {
    this.status = 'started';
    this.browser = await getEnvAwareBrowserInstance();
    this.browser.on('disconnected', async () => {
      try {
        this.browser.removeAllListeners();
      } catch (err) {
        // Optionally handle the error.
      }
      if (this.status === 'started') {
        this.browser = await getEnvAwareBrowserInstance();
      }
    });
  }

  /**
   * Stops the IncognitoBrowser instance.
   * It forcefully kills the browser process (if needed) and then closes the browser.
   */
  public async stop(): Promise<void> {
    this.status = 'stopped';
    const pid = this.browser.process()?.pid;
    if (pid) {
      plugins.treeKill(pid, 'SIGKILL');
    }
    await this.browser.close();
  }

  /**
   * Rotates the browser instance.
   * It closes the current browser and launches a new one.
   */
  public async rotateBrowser(): Promise<void> {
    try {
      await this.browser.close();
    } catch (err) {
      // Ignore errors if the browser is already closed.
    }
    this.browser = await getEnvAwareBrowserInstance();
  }

  /**
   * Returns a new incognito browser context.
   * This uses Puppeteer's createIncognitoBrowserContext() API, which is the
   * correct method for creating isolated sessions.
   */
  public async getNewIncognitoContext(): Promise<plugins.puppeteer.BrowserContext> {
    if (!this.browser) {
      throw new Error('You need to start the IncognitoBrowser instance first');
    }
    // @ts-ignore
    return this.browser.createIncognitoBrowserContext();
  }
}