# Copyright 2026 SigmaSRC, Inc. All Rights Reserved.

"""Gather script for Unix hardware info."""

import os
import re
import sys
import logging

if __name__ == "__main__":
    try:
        import sigma
    except ImportError:
        sys.path.append(os.path.join(os.pardir, os.pardir))

from sigma.gather import gathering

from sigma.util import config

options = config.Options()

# Map ticker symbols to vendor names
tickermap = {
    "SUNW": "Sun Microsystems",
    }

def get_sunos(model):
    vendor = "SUNW"
    p = os.popen("uname -i", "r")
    text = p.readline() # Read the first line
    p.close()
    # uname -i prints "SUNW,xxxxxx"
    # where SUNW is the ticker symbol and xxxxxx the architecture
    if "," in text:
        vendor, model = text.strip().split(",", 1)
    if vendor in tickermap:
        vendor = tickermap[vendor]
    # XXX We assume there are no laptops running Solaris.
    return (vendor, model, 0)

# Strings matching the description strings output from lshw.
# See dmi_chassis() in dmi.cc.
laptops_raw = [
    "Portable Computer",
    "Laptop",
    "Notebook",
    "Hand Held Computer",
    "Sub Notebook",
    ]
laptops = dict([(x.lower(), x) for x in laptops_raw])

def get_linux(machine):
    lshwbin = gathering.get_thirdparty_exe("lshw")
    cmd = lshwbin + " -C system -disable scsi -disable ide -disable cpuid"
    pipe = os.popen(cmd, "r")
    try:
        vendor = ""
        islaptop = 0
        machine = ""
        for line in pipe:
            if ": " in line:
                head, tail = line.split(None, 1)
                if tail:
                    if head == "description:":
                        islaptop = int(tail.strip().lower() in laptops)
                    elif head == "vendor:" and vendor == "":
                        vendor = tail.strip()
                    elif head == "product:" and machine == "":
                        machine = tail.strip()
    finally:
        pipe.close()
    return (vendor, machine, islaptop)

def get_hpux(machine):
    p = os.popen("model")
    model = p.readline().strip()
    p.close()
    return ("Hewlett-Packard", model, 0)

def get_osx(machine):
    model = ""
    regex = re.compile(r"\s*Machine Name:\s*(\S.*\S)\s*$")
    regexM = re.compile(r"\s*Machine Model:\s*(\S.*\S)\s*$")
    pipe = os.popen("/usr/sbin/system_profiler SPHardwareDataType", "r")
    try:
        for line in pipe:
            m = regex.match(line)
            mM = regexM.match(line)
            if m:
                model = m.group(1)
            elif model == "" and mM: 
                model = mM.group(1)
    finally:
        pipe.close()
    return ("Apple", model, int("PowerBook" in model))

def get_aix(machine):
    p = os.popen("uname -M")
    line = p.readline().strip()
    p.close()
    if "," not in line:
        vendor, model = "IBM", ""
    else:
        vendor, model = line.split(",", 1)
    return (vendor, model, 0) # These are not laptops :)

supported = {
    "SunOS": get_sunos,
    "Linux": get_linux,
    "HP-UX": get_hpux,
    "Darwin": get_osx,
    "AIX": get_aix,
    }

def Gather(collector):
    if os.name == "nt":
        from sigma.gather import gather_winhw
        gather_winhw.Gather(collector)
        return
    if not hasattr(os, "uname"):
        raise RuntimeError("Can't gather hardware info on %s system" % os.name)
    system, node, release, version, machine = os.uname()
    doit = supported.get(system)
    if doit is None:
        raise RuntimeError("Can't gather hardware info on %s system" % system)
    table = collector.table("hardware", ["vendor", "model", "laptop"])
    table.add(doit(machine))

def _test():
    gathering.test(Gather)

if __name__ == "__main__":
    _test()
