#
# Copyright (c) 1999--2018 Red Hat, Inc.
#
# This software is licensed to you under the GNU General Public License,
# version 2 (GPLv2). There is NO WARRANTY for this software, express or
# implied, including the implied warranties of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
# along with this software; if not, see
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
#
# Red Hat trademarks are not licensed under GPLv2. No permission is
# granted to use or replicate Red Hat trademarks that are incorporated
# in this software or its documentation.
#

# This thing gets the hardware configuraion out of a system
"""Used to read hardware info from kudzu, /proc, etc"""
from socket import gethostname, getaddrinfo, AF_INET, AF_INET6
import socket
import os
import sys
from up2date_client import config


import gettext
t = gettext.translation('rhn-client-tools', fallback=True)
# Python 3 translations don't have a ugettext method
if not hasattr(t, 'ugettext'):
    t.ugettext = t.gettext
_ = t.ugettext

# Some systems don't have the _locale module installed
try:
    import locale
except ImportError:
    locale = None

def findHostByRoute():
    """ returns [hostname, intf, intf6]

        Where hostname is you FQDN of this machine.
        And intf is numeric IPv4 address. And intf6 is IPv6 address.
    """
    cfg = config.initUp2dateConfig()
    sl = config.getServerURL()

    st = {'https':443, 'http':80}
    hostname = None
    intf = None
    intf6 = None
    for serverUrl in sl:
        server = serverUrl.split('/')[2]
        servertype = serverUrl.split(':')[0]
        port = st[servertype]

        for family in (AF_INET6, AF_INET):
            try:
                s = socket.socket(family)
            except socket.error:
                continue

            if cfg['enableProxy']:
                server_port = config.getProxySetting()
                (server, port) = server_port.split(':')
                port = int(port)

            try:
                s.settimeout(5)
                s.connect((server, port))
                intf_tmp = s.getsockname()[0]
                if family == AF_INET:
                    intf = intf_tmp
                else:
                    intf6 = intf_tmp
                hostname_tmp = socket.getfqdn(intf_tmp)
                if hostname_tmp != intf_tmp:
                    hostname = hostname_tmp
            except socket.error:
                s.close()
                continue
            s.close()

    # Override hostname with the value from /etc/hostname
    if os.path.isfile("/etc/hostname") and os.access("/etc/hostname", os.R_OK):
        hostnameinfo = open("/etc/hostname", "r").readlines()

        for info in hostnameinfo:
            if not len(info):
                continue
            hostname = info.strip()

    # Override hostname with the one in /etc/sysconfig/network
    # for bz# 457953
    elif os.path.isfile("/etc/sysconfig/network") and os.access("/etc/sysconfig/network", os.R_OK):
        networkinfo = open("/etc/sysconfig/network", "r").readlines()

        for info in networkinfo:
            if not len(info):
                continue
            vals = info.split('=')
            if len(vals) <= 1:
                continue
            if vals[0].strip() == "HOSTNAME":
                # /etc/sysconfig/network is of shell syntax,
                # so values can be quoted
                hostname = ''.join(vals[1:]).strip('"\' \t\n')
                break

    if hostname == None or hostname == 'localhost.localdomain':
        hostname = "unknown"
    return hostname, intf, intf6


def read_network():
    netdict = {}
    netdict['class'] = "NETINFO"

    netdict['hostname'], netdict['ipaddr'], netdict['ip6addr'] = findHostByRoute()

    if netdict['hostname'] == "unknown":
        netdict['hostname'] = gethostname()
        if "." not in netdict['hostname']:
            netdict['hostname'] = socket.getfqdn()

    if netdict['ipaddr'] is None:
        try:
            list_of_addrs = getaddrinfo(netdict['hostname'], None)
            ipv4_addrs = filter(lambda x:x[0]==socket.AF_INET, list_of_addrs)
            # take first ipv4 addr
            netdict['ipaddr'] = ipv4_addrs[0][4][0]
        except:
            netdict['ipaddr'] = "127.0.0.1"

    if netdict['ip6addr'] is None:
        try:
            list_of_addrs = getaddrinfo(netdict['hostname'], None)
            ipv6_addrs = filter(lambda x:x[0]==socket.AF_INET6, list_of_addrs)
            # take first ipv6 addr
            netdict['ip6addr'] = ipv6_addrs[0][4][0]
        except:
            netdict['ip6addr'] = "::1"

    if netdict['ipaddr'] is None:
        netdict['ipaddr'] = ''
    if netdict['ip6addr'] is None:
        netdict['ip6addr'] = ''
    return netdict


# this one reads it all
def Hardware():
    allhw = []

    cfg = config.initUp2dateConfig()
    if not cfg["skipNetwork"]:
        # minimal networking info
        try:
            ret = read_network()
            if ret:
                allhw.append(ret)
        except:
            print(_("Error reading networking information:"), sys.exc_info()[0])

    # all Done.
    return allhw

