#!/usr/bin/env python3

import os
import sys
from argparse import ArgumentParser

import yaml
from mako.template import Template

"""
This script generates the data structures for the
phosphor-fan-monitor application.

A future improvement is to get the fan inventory names
from a separate file, so just that file could be generated
from the MRW.
"""


tmpl = """\
<%!
def indent(str, depth):
    return ''.join(4*' '*depth+line for line in str.splitlines(True))
%>\
<%def name="getCondParams(cond)" buffered="True">
%if (cond['name'] == 'propertiesMatch'):
std::vector<PropertyState>{
    %for i in cond['properties']:
    PropertyState{
        {
            "${i['object']}",
            "${i['interface']}",
            "${i['property']['name']}"
        },
        static_cast<${i['property']['type']}>(${str(i['property']['value']).lower()})
    },
    %endfor
}
%endif
</%def>\
/* This is a generated file. */
#include "fan_defs.hpp"
#include "types.hpp"
#include "groups.hpp"
#include "conditions.hpp"

using namespace phosphor::fan::monitor;
using namespace phosphor::fan::trust;

const std::vector<FanDefinition> fanDefinitions
{
%for fan_data in data.get('fans', {}):
    FanDefinition{"${fan_data['inventory']}",
                  ${fan_data.get('method', {})},
                  ${fan_data.get('functional_delay', 0)},
                  ${fan_data.get('allowed_out_of_range_time', {})},
                  ${fan_data['deviation']},
                  ${fan_data.get('upper_deviation', fan_data['deviation'])},
                  ${fan_data['num_sensors_nonfunc_for_fan_nonfunc']},
                  0, // Monitor start delay - not used in YAML configs
                  0, // Count interval - not used in YAML configs
                  std::nullopt, // nonfuncRotorErrorDelay - also not used here
                  std::nullopt, // fanMissingErrorDelay - also not used here
                  std::vector<SensorDefinition>{
                  %for sensor in fan_data['sensors']:
                  <%
                      #has_target is a bool, and we need a true instead of True
                      has_target = str(sensor['has_target']).lower()
                      target_interface = sensor.get(
                          'target_interface',
                          'xyz.openbmc_project.Control.FanSpeed')
                      target_path = sensor.get(
                          'target_path',
                          '')
                      factor = sensor.get('factor', 1)
                      offset = sensor.get('offset', 0)
                      threshold = sensor.get('threshold', 1)
                      ignore_above_max = str(sensor.get(
                          'ignore_above_max', False)).lower()
                  %> \
                      SensorDefinition{"${sensor['name']}",
                                       ${has_target},
                                       "${target_interface}",
                                       "${target_path}",
                                       ${factor},
                                       ${offset},
                                       ${threshold},
                                       ${ignore_above_max}},
                  %endfor
                  },
                  %if ('condition' in fan_data) and \
                  (fan_data['condition'] is not None):
                  make_condition(condition::${fan_data['condition']['name']}(\
                      ${indent(getCondParams(cond=fan_data['condition']), 5)}\
                  )),
                  %else:
                  {},
                  %endif
                  false // set_func_on_present. Hardcoded to false.
    },
%endfor
};

##Function to generate the group creation lambda.
##If a group were to ever need a different constructor,
##it could be handled here.
<%def name="get_lambda_contents(group)">
            std::vector<GroupDefinition> group{
            %for member in group['group']:
            <%
                in_trust = str(member.get('in_trust', "true")).lower()
            %>
                GroupDefinition{"${member['name']}", ${in_trust}},
            %endfor
            };
            return std::make_unique<${group['class']}>(group);
</%def>
const std::vector<CreateGroupFunction> trustGroups
{
%for group in data.get('sensor_trust_groups', {}):
    {
        []()
        {\
${get_lambda_contents(group)}\
        }
    },
%endfor
};
"""


if __name__ == "__main__":
    parser = ArgumentParser(
        description="Phosphor fan monitor definition parser"
    )

    parser.add_argument(
        "-m",
        "--monitor_yaml",
        dest="monitor_yaml",
        default="example/monitor.yaml",
        help="fan monitor definitional yaml",
    )
    parser.add_argument(
        "-o",
        "--output_dir",
        dest="output_dir",
        default=".",
        help="output directory",
    )
    args = parser.parse_args()

    if not args.monitor_yaml:
        parser.print_usage()
        sys.exit(1)

    with open(args.monitor_yaml, "r") as monitor_input:
        monitor_data = yaml.safe_load(monitor_input) or {}

    # Do some minor input validation
    for fan in monitor_data.get("fans", {}):
        if (fan["deviation"] < 0) or (fan["deviation"] > 100):
            sys.exit("Invalid deviation value " + str(fan["deviation"]))

    output_file = os.path.join(args.output_dir, "fan_monitor_defs.cpp")
    with open(output_file, "w") as output:
        output.write(Template(tmpl).render(data=monitor_data))
