private static Course ExtractCourse(Config config)
        {
            Course course = new Course();

            Extractor.ExtractCourseStructure(out int videosCount);
            using (pbarExtractor = new ProgressBar(videosCount, "Extracting Course Links - This will take some time", optionPbarExtractor))
            {
                Retry.Do(
                    function: () =>
                {
                    Log.Information("Extracting...");
                    Extractor.ExtractionProgressChanged += Extractor_ExtractionProgressChanged;
                    course = Extractor.ExtractCourse(config.Quality);
                },
                    exceptionMessage: "An error occured while extracting the course",
                    actionOnError: () =>
                {
                    Extractor.CloseTabs();
                    var progress = pbarExtractor.AsProgress <float>();
                    progress?.Report(0);
                    Extractor.ExtractionProgressChanged -= Extractor_ExtractionProgressChanged;
                },
                    actionOnFatal: () =>
                {
                    TUI.ShowError("Failed to extract course. You can find more info in the logs");
                    Log.Error("Unknown error occured. Running app again");
                    TUI.ShowError("Unknown error occured");
                    TUI.ShowError("Restarting...");
                    Extractor.KillDrivers();
                    Extractor.ExtractionProgressChanged -= Extractor_ExtractionProgressChanged;
                    course = null;
                }
                    );
            }

            return(course);
        }
        private Course ExtractCourse()
        {
            Course course = new Course();

            UpdateUI(() => lblCurrentOperation.Text = "Logging in");
            Browser browser = GetFromUI <Browser>(() => cmboxBrowser.SelectedIndex);

            Log.Information("Logging in");
            Extractor.InitializeDriver(browser);
            try
            {
                Extractor.Login(txtToken.Text, txtCourseUrl.Text).Wait();
                Log.Information("Logged in with course url : {0} and token of {1} characters", GetFromUI <string>(() => txtCourseUrl.Text), GetFromUI <int>(() => txtToken.Text.Length));
                UpdateUI(() =>
                {
                    lblCurrentOperation.Text = "Logged in successfully";
                    UC_IsLoggedin.IsLoggedin = true;
                });
            }
            catch (InvalidTokenException ex)
            {
                MessageBox.Show("The token or the course url you provided is invalid.\nPlease make sure you entered the right token and course url", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
                UpdateUI(() =>
                {
                    EnableControls(true);
                    lblCurrentOperation.Text = "Login Failed";
                });
                Log.Error(ex, "Failed to log in with course url : {0} and token of {1} characters", GetFromUI <string>(() => txtCourseUrl.Text), GetFromUI <int>(() => txtToken.Text.Length));
                return(null);
            }
            catch (Exception e) when(e.InnerException is InvalidTokenException ex)
            {
                MessageBox.Show("The token or the course url you provided is invalid.\nPlease make sure you entered the right token and course url", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
                UpdateUI(() =>
                {
                    EnableControls(true);
                    lblCurrentOperation.Text = "Login Failed";
                });
                Log.Error(ex, "Failed to log in with course url : {0} and token of {1} characters", GetFromUI <string>(() => txtCourseUrl.Text), GetFromUI <int>(() => txtToken.Text.Length));
                return(null);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Unknown Exception");
                throw ex;
            }

            UpdateUI(() =>
            {
                lblCurrentOperation.Text        = "Starting Course Extractor";
                UC_CourseExtractorStatus.Status = CourseStatus.Starting;
            });
            Extractor.ExtractCourseStructure(out _videosCount);
            Quality quality = GetFromUI <Quality>(() => cmboxQuality.SelectedIndex);

            UpdateUI(() =>
            {
                lblCurrentOperation.Text        = $"Extracting Course...[0/{_videosCount}]";
                UC_CourseExtractorStatus.Status = CourseStatus.Running;
            });
            bool isExtracted = true;

            Retry.Do(
                function: () =>
            {
                Extractor.ExtractionProgressChanged += Extractor_ExtractionProgressChanged;
                course = Extractor.ExtractCourse(quality);
            },
                exceptionMessage: "An error occured while extracting the course",
                actionOnError: () =>
            {
                MessageBox.Show($"An error occured while extracting the course.\nTrying again", "Unknown Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                UpdateUI(() =>
                {
                    progressBar.Value  = 0;
                    _currentVideoIndex = 0;
                    Extractor.ExtractionProgressChanged -= Extractor_ExtractionProgressChanged;
                });
                Extractor.CloseTabs();
            },
                actionOnFatal: () =>
            {
                Extractor.KillDrivers();
                UpdateUI(() =>
                {
                    EnableControls(true);
                    UC_CourseExtractorStatus.Status = CourseStatus.Failed;
                    lblCurrentOperation.Text        = "Course Extraction Failed";
                });
                isExtracted = false;
            });

            if (!isExtracted)
            {
                return(null);
            }
            UpdateUI(() =>
            {
                lblCurrentOperation.Text        = "Course Extracted Successfully";
                UC_CourseExtractorStatus.Status = CourseStatus.Finished;
            });
            return(course);
        }