#!/usr/bin/env perl

#Creates a configuration file for each hwmon sensor in the MRW
#for use by the phosphor-hwmon daemon.  These configuration files
#contain labels and thresholds for the hwmon features for that sensor.
#The files are created in subdirectories based on their device
#tree paths.

use strict;
use warnings;

use mrw::Targets;
use mrw::Util;
use Getopt::Long;
use File::Path qw(make_path);

use constant {
    I2C_TYPE => "i2c"
};

my $serverwizFile;
my @hwmon;

GetOptions("x=s" => \$serverwizFile) or printUsage();

if (not defined $serverwizFile) {
    printUsage();
}

my $g_targetObj = Targets->new;
$g_targetObj->loadXML($serverwizFile);

my $bmc = Util::getBMCTarget($g_targetObj);

getI2CSensors($bmc, \@hwmon);

makeConfFiles($bmc, \@hwmon);

exit 0;


#Returns an array of hashes that represent hwmon enabled I2C sensors.
sub getI2CSensors
{
    my ($bmc, $hwmon) = @_;
    my $connections = $g_targetObj->findConnections($bmc, "I2C");

    return if ($connections eq "");

    for my $i2c (@{$connections->{CONN}}) {

        my $chip = $i2c->{DEST_PARENT};
        my @hwmonUnits = Util::getChildUnitsWithTargetType($g_targetObj,
                                                      "unit-hwmon-feature",
                                                      $chip);

        #If chip didn't have hwmon units, it isn't hwmon enabled.
        next unless (scalar @hwmonUnits > 0);

        my %entry;
        $entry{type} = I2C_TYPE;
        $entry{name} = lc $g_targetObj->getInstanceName($chip);
        getHwmonAttributes(\@hwmonUnits, \%entry);
        getI2CAttributes($i2c, \%entry);

        push @$hwmon, { %entry };
    }
}


#Reads the hwmon related attributes from the HWMON_FEATURE
#complex attribute and adds them to the hash.
sub getHwmonAttributes
{
    my ($units, $entry) = @_;
    my %hwmonFeatures;

    for my $unit (@$units) {

        #The hwmon name, like 'in1', 'temp1', 'fan1', etc
        my $hwmon = $g_targetObj->getAttributeField($unit,
                                                    "HWMON_FEATURE",
                                                    "HWMON_NAME");

        #The useful name for this feature, like 'ambient'
        my $name = $g_targetObj->getAttributeField($unit,
                                                   "HWMON_FEATURE",
                                                   "DESCRIPTIVE_NAME");
        $hwmonFeatures{$hwmon}{label} = $name;

        #Thresholds are optional, ignore if NA
        my $warnHigh = $g_targetObj->getAttributeField($unit,
                                                       "HWMON_FEATURE",
                                                       "WARN_HIGH");
        if (($warnHigh ne "") && ($warnHigh ne "NA")) {
            $hwmonFeatures{$hwmon}{warnhigh} = $warnHigh;
        }

        my $warnLow = $g_targetObj->getAttributeField($unit,
                                                      "HWMON_FEATURE",
                                                      "WARN_LOW");
        if (($warnLow ne "") && ($warnLow ne "NA")) {
            $hwmonFeatures{$hwmon}{warnlow} = $warnLow;
        }

        my $critHigh = $g_targetObj->getAttributeField($unit,
                                                       "HWMON_FEATURE",
                                                       "CRIT_HIGH");
        if (($critHigh ne "") && ($critHigh ne "NA")) {
            $hwmonFeatures{$hwmon}{crithigh} = $critHigh;
        }

        my $critLow = $g_targetObj->getAttributeField($unit,
                                                      "HWMON_FEATURE",
                                                      "CRIT_LOW");
        if (($critLow ne "") && ($critHigh ne "NA")) {
            $hwmonFeatures{$hwmon}{critlow} = $critLow;
        }
    }

    $entry->{hwmon} = { %hwmonFeatures };
}


#Reads the I2C attributes for the chip and adds them to the hash.
#This includes the i2C address, and register base address and
#offset for the I2C bus the chip is on.
sub getI2CAttributes
{
    my ($i2c, $entry) = @_;

    #The address comes from the destination unit, and needs
    #to be the 7 bit value in hex without the 0x.
    my $addr = $g_targetObj->getAttribute($i2c->{DEST}, "I2C_ADDRESS");
    $addr = hex($addr) >> 1;
    $entry->{addr} = sprintf("%x", $addr);

    #The reg base address and offset may be optional depending on
    #the BMC chip type.  We'll check later if it's required but missing.
    if (!$g_targetObj->isBadAttribute($i2c->{SOURCE}, "REG_BASE_ADDRESS")) {
        my $addr = $g_targetObj->getAttribute($i2c->{SOURCE},
                                              "REG_BASE_ADDRESS");
        $entry->{regBaseAddress} = sprintf("%x", hex($addr));
    }

    if (!$g_targetObj->isBadAttribute($i2c->{SOURCE}, "REG_OFFSET")) {
        my $offset = $g_targetObj->getAttribute($i2c->{SOURCE},
                                                "REG_OFFSET");
        $entry->{regOffset} = sprintf("%x", hex($offset));
    }
}


#Creates .conf files for each chip.
sub makeConfFiles
{
    my ($bmc, $hwmon) = @_;

    for my $entry (@$hwmon) {
        printConfFile($bmc, $entry);
    }
}


#Writes out a configuration file for a hwmon sensor, containing:
#  LABEL_<feature> = <descriptive label>  (e.g. LABEL_temp1 = ambient)
#  WARNHI_<feature> = <value> (e.g. WARNHI_temp1 = 99)
#  WARNLO_<feature> = <value> (e.g. WARNLO_temp1 = 0)
#  CRITHI_<feature> = <value> (e.g. CRITHI_temp1 = 100)
#  CRITHI_<feature> = <value> (e.g. CRITLO_temp1 = -1)
#
#  The file is created in a subdirectory based on the chip's device
#  tree path.
sub printConfFile
{
    my ($bmc, $entry) = @_;
    my $path = getConfFilePath($bmc, $entry);
    my $name = $path . "/" . getConfFileName($entry);

    make_path($path);

    open(my $f, ">$name") or die "Could not open $name\n";

    for my $feature (sort keys %{$entry->{hwmon}}) {
        print $f "LABEL_$feature = \"$entry->{hwmon}{$feature}{label}\"\n";

        #Thresholds are optional
        if (exists $entry->{hwmon}{$feature}{warnhigh}) {
            print $f "WARNHI_$feature = \"$entry->{hwmon}{$feature}{warnhigh}\"\n";
        }
        if (exists $entry->{hwmon}{$feature}{warnlow}) {
            print $f "WARNLO_$feature = \"$entry->{hwmon}{$feature}{warnlow}\"\n";
        }
        if (exists $entry->{hwmon}{$feature}{crithigh}) {
            print $f "CRITHI_$feature = \"$entry->{hwmon}{$feature}{crithigh}\"\n";
        }
        if (exists $entry->{hwmon}{$feature}{critlow}) {
            print $f "CRITLO_$feature = \"$entry->{hwmon}{$feature}{critlow}\"\n";
        }
    }

    close $f;
}


#Returns the chip's configuration file path.
sub getConfFilePath
{
    my ($bmc, $entry) = @_;

    my $mfgr = $g_targetObj->getAttribute($bmc, "MANUFACTURER");

    #Unfortunately, because the conf file path is based on the
    #device tree path which is tied to the internal chip structure,
    #this has to be model specific.  Until proven wrong, I'm going
    #to make an assumption that all ASPEED chips have the same path
    #as so far all of the models I've seen do.
    if ($mfgr eq "ASPEED") {
        return getAspeedConfFilePath($entry);
    }
    else {
        die "Unsupported BMC manufacturer $mfgr\n";
    }
}


#Returns the relative path of the configuration file to create.
#This path is based on the path of the chip in the device tree.
#An example path is  ahb/apb/i2c@1e78a000/i2c-bus@400/
sub getAspeedConfFilePath
{
    my ($entry) = @_;
    my $path;

    if ($entry->{type} eq I2C_TYPE) {

        #ASPEED requires the reg base address & offset fields
        if ((not exists $entry->{regBaseAddress}) ||
            (not exists $entry->{regOffset})) {
            die "Missing regBaseAddress or regOffset attributes " .
                "in the I2C master unit XML\n";
        }

        $path = "ahb/apb/i2c\@$entry->{regBaseAddress}/i2c-bus@" .
                "$entry->{regOffset}";
    }
    else {
        #TODO: FSI support for the OCC when known
        die "HWMON bus type $entry->{type} not implemented yet\n";
    }

    return $path;
}


#Returns the name to use for the conf file:
#  <name>@<addr>.conf  (e.g. rtc@68.conf)
sub getConfFileName
{
    my ($entry) = @_;
    return "$entry->{name}\@$entry->{addr}.conf";
}


sub printUsage
{
    print "$0 -x [XML filename]\n";
    exit(1);
}
