require 'rspec/expectations'
require './core/utils/logger_utils.rb'
require 'smoca_common/utils/twitch_utils'

class PageHelper
  @loading_mask = '.loading-mask'
  @notification_container = 'div.noty_message'
  @notification_close = 'div.noty_close'

  class << self
    @@browser_window_size_changed = false
    @@default_browser_width       = 1500
    @@default_browser_height      = 800

    attr_reader :default_browser_width, :default_browser_height, :notification_container, :notification_close, :loading_mask

    include RSpec::Matchers
    include Capybara::DSL
    include Capybara::RSpecMatchers
    include LoggerUtils

    def clear_cookies
      browser = Capybara.current_session.driver.browser
      if browser.respond_to?(:manage) and browser.manage.respond_to?(:delete_all_cookies)
        # Selenium::WebDriver
        browser.manage.delete_all_cookies
      else
        raise 'Unable to reset cookies.'
      end
    end

    def signup_modal()
      # TODO: Deprecate ASAP. Should be in Signup Helpers, and should tie in better with those helpers
      # https://twitchtv.atlassian.net/browse/SMOC-82

      begin
        expect(page).to have_css('#signup_form')
      rescue Exception => e # Passport V2 has things different. Catch this for now.
        # TODO: Kill the above logic, make this default when Passport V2 is released.
        raise e if !e.message == 'expected to find css "#signup_form" but there were no matches'

        within '.js-login-popup' do
          find('iframe', wait: 6) # This is Passport. Give it 6 seconds to load
        end

        within_frame('passport') do
          expect(page).to have_css('#signupForm')
        end
      end
    end

    # Adjust the size of the Browser for Selenium Grid
    # Headless browser is not supported by this method
    # @param width Width of the browser window
    # @param height Height of the browser window
    def resize_browser_window(width, height)
      window = Capybara.current_session.driver.browser.manage.window
      window.resize_to(width, height) # width, height

      if width != @@default_browser_width || height != @@default_browser_height
        @@browser_window_size_changed = true
      end
    end

    # Adjust the size of the Browser for Selenium Grid back to default
    # Headless browser is not supported by this method
    def reset_browser_window_size
      return unless @@browser_window_size_changed

      set_browser_window_to_default_size
      @@browser_window_size_changed = false
    end

    def set_browser_window_to_default_size
      resize_browser_window(@@default_browser_width, @@default_browser_height)
    end

    # Adds a cookie to the browser on the current domain.
    # Selenium does not seem to support adding a cookie for the non-current domain.
    # Recommend refreshing after setting the cookie.
    # @param name [String] - The cookie name you would like to set
    # @param value [String] - The cookie value you would like to set
    def add_cookie(name, value)
      puts 'Warning! Cookie adding not tested on non selenium driver.' if Capybara.current_session.driver.class != Capybara::Selenium::Driver
      page.driver.browser.manage.add_cookie(:name => name, :value => value)
    end

    # A simple get method to return the name of the Captcha Bypass cookie, thus reducing hardcoded names
    # @return [String] Cookie name to bypass
    def get_captcha_bypass_cookie_name
      return 'passport_trusted_request'
    end

    # @return [Hash] Information on the cookie if exists
    # @return [Nil] When nothing is returned
    def get_cookie(name)
      return page.driver.browser.manage.cookie_named(name)
    end

    # Check if the login page has captcha, bypass it by setting a special cookie.
    # Only works to bypass on the internal network.
    # https://git-aws.internal.justin.tv/web/passport#bypassing-captchas
    def add_bypass_cookie
      add_cookie(get_captcha_bypass_cookie_name, '1')
    end

    # Sets a cookie to bypass captcha
    # Useful for setting this before a scenario
    def set_bypass_captcha_cookie
      visit '/login'
      add_bypass_cookie
    end

    # Recovers from a captcha if it discovers a captcha on the current page.
    # Useful for methods outside of the login spec that need to rely on login.
    def handle_captcha
      if have_css('.g-recaptcha')
        add_bypass_cookie # Allow to log in without captcha
        visit current_url
      end
    end

    # @return [Boolean] If page has been loaded.
    def has_loaded?
      # Wait for spinner to appear on screen
      page.has_selector?(PageHelper.loading_mask, wait: 5)
      # Wait for spinner to disappear from screen
      return page.has_no_selector?(PageHelper.loading_mask, wait: 20)
    end

    # Closes the twitch notification if displayed at the bottom of the page
    def dismiss_notification
      # wait to see if the page will have notifications on page after 3 seconds
      # if so, close the notification
      if page.has_selector?(PageHelper.notification_container, wait: 3)
        placeholders = page.all(PageHelper.notification_container)
        placeholders.each do |placeholder|
          within(placeholder) do
            find(PageHelper.notification_close).click
          end
        end
      end
    end
  end
end
