#!/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['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))
