# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This module has the class for controlling Mini-Circuits RCDAT series
attenuators over Telnet.

See http://www.minicircuits.com/softwaredownload/Prog_Manual-6-Programmable_Attenuator.pdf
"""

from mobly.controllers import attenuator
from mobly.controllers.attenuator_lib import telnet_scpi_client


class AttenuatorDevice(object):
    """This provides a specific telnet-controlled implementation of
    AttenuatorDevice for Mini-Circuits RC-DAT attenuators.

    Attributes:
        path_count: The number of signal attenuation path this device has.
    """

    def __init__(self, path_count=1):
        self.path_count = path_count
        # The telnet client used to communicate with the attenuator device.
        self._telnet_client = telnet_scpi_client.TelnetScpiClient(
            tx_cmd_separator="\r\n", rx_cmd_separator="\r\n", prompt="")

    @property
    def is_open(self):
        """This function returns the state of the telnet connection to the
        underlying AttenuatorDevice.

        Returns:
            True if there is a successfully open connection to the
            AttenuatorDevice.
        """
        return bool(self._telnet_client.is_open)

    def open(self, host, port=23):
        """Opens a telnet connection to the desired AttenuatorDevice and
        queries basic information.

        Args:
            host: A valid hostname (IP address or DNS-resolvable name) to an
                MC-DAT attenuator instrument.
            port: An optional port number (defaults to telnet default 23)
        """
        self._telnet_client.open(host, port)
        config_str = self._telnet_client.cmd("MN?")
        if config_str.startswith("MN="):
            config_str = config_str[len("MN="):]
        self.properties = dict(
            zip(['model', 'max_freq', 'max_atten'], config_str.split("-", 2)))
        self.max_atten = float(self.properties['max_atten'])

    def close(self):
        """Closes a telnet connection to the desired attenuator device.

        This should be called as part of any teardown procedure prior to the
        attenuator instrument leaving scope.
        """
        if self.is_open:
            self._telnet_client.close()

    def set_atten(self, idx, value):
        """Sets the attenuation value for a particular signal path.

        Args:
            idx: Zero-based index int which is the identifier for a particular
                signal path in an instrument. For instruments that only has one
                channel, this is ignored by the device.
            value: A float that is the attenuation value to set.

        Raises:
            Error: The underlying telnet connection to the instrument is not
                open.
            IndexError: The index of the attenuator is greater than the maximum
                index of the underlying instrument.
            ValueError: The requested set value is greater than the maximum
                attenuation value.
        """
        if not self.is_open:
            raise attenuator.Error(
                "Connection to attenuator at %s is not open!" %
                self._telnet_client.host)
        if idx + 1 > self.path_count:
            raise IndexError("Attenuator index out of range!", self.path_count,
                             idx)
        if value > self.max_atten:
            raise ValueError("Attenuator value out of range!", self.max_atten,
                             value)
        # The actual device uses one-based index for channel numbers.
        self._telnet_client.cmd("CHAN:%s:SETATT:%s" % (idx + 1, value))

    def get_atten(self, idx=0):
        """This function returns the current attenuation from an attenuator at a
        given index in the instrument.

        Args:
            idx: This zero-based index is the identifier for a particular
                attenuator in an instrument.

        Raises:
            Error: The underlying telnet connection to the instrument is not
                open.

        Returns:
            A float that is the current attenuation value.
        """
        if not self.is_open:
            raise attenuator.Error(
                "Connection to attenuator at %s is not open!" %
                self._telnet_client.host)
        if idx + 1 > self.path_count or idx < 0:
            raise IndexError("Attenuator index out of range!", self.path_count,
                             idx)
        atten_val_str = self._telnet_client.cmd("CHAN:%s:ATT?" % (idx + 1))
        atten_val = float(atten_val_str)
        return atten_val
