using Beam.Abstractions;
using Beam.Downloaders;
using Beam.Models;
using Beam.Playwright.Strategies;
using Microsoft.Playwright;

namespace Beam.Playwright {
    public class PlaywrightUnitDownloader<OutType> : UnitDownloader<OutType> {
        public PlaywrightUnitDownloader(UnitDownloaderOptions<OutType> options,
            PlaywrightAsyncManipulator puppetManipulator) : base(options) {
            PuppetManipulator = puppetManipulator;

            _downloadStrategy = options.Target switch {
                DownloadTarget.URL or DownloadTarget.InURL => new PageDownloadStrategy(),
                DownloadTarget.Complex => new WaitingDownloadStrategy(),
                _ => throw new NotSupportedException() // TODO add an exception message
            };
        }

        public PlaywrightAsyncManipulator PuppetManipulator { get; }
        private IDownloadStrategy _downloadStrategy { get; }
        
        protected override async Task DownloadToStream(string url, int bufferSize, Stream destinationStream, IProgress<IDownloadReport> progress, CancellationToken ct) {
            var page = await PlaywrightContext.Browser.Value.NewPageAsync();
            try {
                await page.GotoAsync(url);
                await PuppetManipulator(page);
                await _downloadStrategy.DownloadToStream(url, bufferSize, destinationStream, progress, page, ct);
            } finally {
                if (!page.IsClosed)
                    await page.CloseAsync();
            }
        }
    }

}
