# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Class to control the Linksys WRT54G2 router."""

import logging
import urlparse

import dynamic_ap_configurator
import ap_spec


class LinksysAPConfigurator(
        dynamic_ap_configurator.DynamicAPConfigurator):
    """Derived class to control Linksys WRT54G2 router."""


    def _sec_alert(self, alert):
        text = alert.text
        if 'Invalid Key, must be between 8 and 63 ASCII' in text:
            raise RuntimeError('We got a modal dialog. ' + text)
        else:
            raise RuntimeError('Unhandled alert message: %s' % text)


    def get_number_of_pages(self):
        return 2


    def get_supported_bands(self):
        return [{'band': ap_spec.BAND_2GHZ,
                 'channels': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}]


    def get_supported_modes(self):
        return [{'band': ap_spec.BAND_2GHZ,
                 'modes': [ap_spec.MODE_B, ap_spec.MODE_G, ap_spec.MODE_B |
                           ap_spec.MODE_G]}]


    def is_security_mode_supported(self, security_mode):
        return security_mode in (ap_spec.SECURITY_TYPE_DISABLED,
                                 ap_spec.SECURITY_TYPE_WPAPSK,
                                 ap_spec.SECURITY_TYPE_WPA2PSK,
                                 ap_spec.SECURITY_TYPE_WEP)


    def navigate_to_page(self, page_number):
        if page_number == 1:
            url = urlparse.urljoin(self.admin_interface_url, 'wireless.htm')
            self.driver.get(url)
            xpath = '//input[@name="wsc_smode" and @value=1]'
            button = self.driver.find_element_by_xpath(xpath)
            if not button.is_selected():
                self.click_button_by_xpath(xpath)
        elif page_number == 2:
            url = urlparse.urljoin(self.admin_interface_url, 'WSecurity.htm')
            self.driver.get(url)
        else:
            raise RuntimeError('Invalid page number passed.  Number of pages '
                               '%d, page value sent was %d' %
                               (self.get_number_of_pages(), page_number))


    def save_page(self, page_number):
        self.wait_for_object_by_id('divBT1')
        self.click_button_by_xpath('id("divBT1")')
        # Wait for the continue button
        continue_xpath = '//input[@value="Continue" and @type="button"]'
        self.wait_for_object_by_xpath(continue_xpath)
        self.click_button_by_xpath(continue_xpath,
                                   alert_handler=self._sec_alert)


    def set_mode(self, mode, band=None):
        self.add_item_to_command_list(self._set_mode, (mode,), 1, 900)


    def _set_mode(self, mode):
        # Different bands are not supported so we ignore.
        # Create the mode to popup item mapping
        mode_mapping = {ap_spec.MODE_B: 'B-Only', ap_spec.MODE_G: 'G-Only',
                        ap_spec.MODE_B | ap_spec.MODE_G: 'Mixed',
                        'Disabled': 'Disabled'}
        mode_name = mode_mapping.get(mode)
        if not mode_name:
            raise RuntimeError('The mode selected %d is not supported by router'
                               ' %s.', hex(mode), self.name)
        xpath = ('//select[@onchange="SelWL()" and @name="Mode"]')
        self.select_item_from_popup_by_xpath(mode_name, xpath)


    def set_radio(self, enabled=True):
        # If we are enabling we are activating all other UI components, do it
        # first.  Otherwise we are turning everything off so do it last.
        weight = 1 if enabled else 1000
        self.add_item_to_command_list(self._set_radio, (enabled,), 1, weight)


    def _set_radio(self, enabled=True):
        xpath = ('//select[@onchange="SelWL()" and @name="Mode"]')
        # To turn off we pick disabled, to turn on we set to G
        if not enabled:
            self._set_mode('Disabled')
        else:
            self._set_mode(ap_spec.MODE_G)


    def set_ssid(self, ssid):
        self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900)


    def _set_ssid(self, ssid):
        self._set_radio(enabled=True)
        xpath = ('//input[@maxlength="32" and @name="SSID"]')
        self.set_content_of_text_field_by_xpath(ssid, xpath)
        self._ssid = ssid


    def set_channel(self, channel):
        self.add_item_to_command_list(self._set_channel, (channel,), 1, 900)


    def _set_channel(self, channel):
        position = self._get_channel_popup_position(channel)
        self._set_radio(enabled=True)
        channel_choices = ['1 - 2.412GHz', '2 - 2.417GHz', '3 - 2.422GHz',
                           '4 - 2.427GHz', '5 - 2.432GHz', '6 - 2.437GHz',
                           '7 - 2.442GHz', '8 - 2.447GHz', '9 - 2.452GHz',
                           '10 - 2.457GHz', '11 - 2.462GHz']
        xpath = ('//select[@onfocus="check_action(this,0)" and @name="Freq"]')
        self.select_item_from_popup_by_xpath(channel_choices[position],
                                             xpath)


    def set_band(self, band):
        return None


    def set_security_disabled(self):
        self.add_item_to_command_list(self._set_security_disabled, (), 2, 1000)


    def _set_security_disabled(self):
        xpath = ('//select[@name="SecurityMode"]')
        self.select_item_from_popup_by_xpath('Disabled', xpath)


    def set_security_wep(self, key_value, authentication):
        self.add_item_to_command_list(self._set_security_wep,
                                      (key_value, authentication), 2, 1000)


    def _set_security_wep(self, key_value, authentication):
        logging.debug('This router %s doesnt support WEP authentication type: '
                      '%s', self.name, authentication)
        popup = '//select[@name="SecurityMode"]'
        self.wait_for_object_by_xpath(popup)
        text_field = ('//input[@name="wl_passphrase"]')
        self.select_item_from_popup_by_xpath('WEP', popup,
                                             wait_for_xpath=text_field,
                                             alert_handler=self._sec_alert)
        self.set_content_of_text_field_by_xpath(key_value, text_field,
                                                abort_check=True)
        self.click_button_by_xpath('//input[@value="Generate"]',
                                   alert_handler=self._sec_alert)


    def set_security_wpapsk(self, security, shared_key, update_interval=1800):
        self.add_item_to_command_list(self._set_security_wpapsk,
                                      (security, shared_key, update_interval),
                                       2, 900)


    def _set_security_wpapsk(self, security, shared_key, update_interval=1800):
        if update_interval < 600:
            logging.debug('The minimum update interval is 600, overriding.')
            update_interval = 600
        elif update_interval > 7200:
            logging.debug('The maximum update interval is 7200, overriding.')
            update_interval = 7200
        popup = '//select[@name="SecurityMode"]'
        self.wait_for_object_by_xpath(popup)
        key_field = '//input[@name="PassPhrase"]'
        if security == ap_spec.SECURITY_TYPE_WPAPSK:
            wpa_item = 'WPA Personal'
        else:
            wpa_item = 'WPA2 Personal'
        self.select_item_from_popup_by_xpath(wpa_item, popup,
                                             wait_for_xpath=key_field,
                                             alert_handler=self._sec_alert)
        self.set_content_of_text_field_by_xpath(shared_key, key_field,
                                                abort_check=True)
        interval_field = ('//input[@name="GkuInterval"]')
        self.set_content_of_text_field_by_xpath(str(update_interval),
                                                interval_field)


    def set_visibility(self, visible=True):
        self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900)


    def _set_visibility(self, visible=True):
        self._set_radio(enabled=True)
        # value=1 is visible; value=0 is invisible
        int_value = int(visible)
        xpath = ('//input[@value="%d" and @name="wl_closed"]' % int_value)
        self.click_button_by_xpath(xpath)
