# osmo_gsm_tester: class defining a Power Supply object
#
# Copyright (C) 2019 by sysmocom - s.f.m.c. GmbH
#
# Author: Pau Espin Pedrol <pespin@sysmocom.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import urllib.request
import xml.etree.ElementTree as ET

from ..core import log
from .powersupply import PowerSupply

class PowerSupplyIntellinet(PowerSupply):
    """PowerSupply implementation to controll Intellinet devices."""

    # HTTP request timeout, in seconds
    PDU_TIMEOUT = 5

    PDU_CMD_ON = 0
    PDU_CMD_OFF = 1

    def _url_prefix(self):
        return 'http://' + self.device_ip

    def _url_status(self):
        return self._url_prefix() + '/status.xml'

    def _url_set_port_status(self, pdu_cmd):
        return self._url_prefix() + "/control_outlet.htm?" + "outlet" + str(self.port - 1) + "=1" + "&op=" + str(pdu_cmd) + "&submit=Anwenden"

    def _port_stat_name(self):
        # Names start with idx 0, while in ogt we count sockets starting from 1.
        return 'outletStat' + str(self.port - 1)

    def _fetch_status(self):
        data = urllib.request.urlopen(self._url_status(), timeout = self.PDU_TIMEOUT).read()
        if not data:
            raise log.Error('empty status xml')
        return data

    def _get_port_status(self):
        data = self._fetch_status()
        root = ET.fromstring(data)
        for child in root:
            if child.tag == self._port_stat_name():
                return child.text
        raise log.Error('no state for %s' % self._port_stat_name())

    def _set_port_status(self, pdu_cmd):
        urllib.request.urlopen(self._url_set_port_status(pdu_cmd),timeout = self.PDU_TIMEOUT).read()


########################
# PUBLIC - INTERNAL API
########################
    def __init__(self, conf):
        super().__init__(conf, 'intellinet')
        mydevid = conf.get('device')
        if mydevid is None:
            raise log.Error('No "device" attribute provided in supply conf!')
        self.set_name('intellinet-'+mydevid)
        myport = conf.get('port')
        if myport is None:
            raise log.Error('No "port" attribute provided in power_supply conf!')
        if not int(myport):
            raise log.Error('Wrong non numeric "port" attribute provided in power_supply conf!')
        self.set_name('intellinet-'+mydevid+'-'+myport)
        self.device_ip = mydevid
        self.port = int(myport)

    def is_powered(self):
        """Get whether the device is powered on or off."""
        return self._get_port_status() == 'on'

    def power_set(self, onoff):
        """Turn on (onoff=True) or off (onoff=False) the device."""
        if onoff:
            self.dbg('switchon %s:%u' % (self.device_ip, self.port))
            self._set_port_status(self.PDU_CMD_ON)
        else:
            self.dbg('switchoff %s:%u' % (self.device_ip, self.port))
            self._set_port_status(self.PDU_CMD_OFF)


# vim: expandtab tabstop=4 shiftwidth=4
