#!/usr/bin/env python

"""
This script reads in fan definition and zone definition YAML
files and generates a set of structures for use by the fan control code.
"""

import os
import sys
import yaml
from argparse import ArgumentParser
from mako.template import Template

tmpl = '''/* This is a generated file. */
#include <sdbusplus/bus.hpp>
#include "manager.hpp"
#include "functor.hpp"
#include "actions.hpp"
#include "handlers.hpp"

using namespace phosphor::fan::control;
using namespace sdbusplus::bus::match::rules;

const unsigned int Manager::_powerOnDelay{${mgr_data['power_on_delay']}};

const std::vector<ZoneGroup> Manager::_zoneLayouts
{
%for zone_group in zones:
    ZoneGroup{
        std::vector<Condition>{
        %for condition in zone_group['conditions']:
            Condition{
                "${condition['type']}",
                std::vector<ConditionProperty>{
                %for property in condition['properties']:
                    ConditionProperty{
                        "${property['property']}",
                        "${property['interface']}",
                        "${property['path']}",
                        static_cast<${property['type']}>(${property['value']}),
                    },
                    %endfor
                },
            },
            %endfor
        },
        std::vector<ZoneDefinition>{
        %for zone in zone_group['zones']:
            ZoneDefinition{
                ${zone['num']},
                ${zone['full_speed']},
                std::vector<FanDefinition>{
                %for fan in zone['fans']:
                    FanDefinition{
                        "${fan['name']}",
                        std::vector<std::string>{
                        %for sensor in fan['sensors']:
                            "${sensor}",
                        %endfor
                        }
                    },
                %endfor
                },
                std::vector<SetSpeedEvent>{
                %for event in zone['events']:
                    SetSpeedEvent{
                        Group{
                        %for member in event['group']:
                        {
                            "${member['name']}",
                            {"${member['interface']}",
                             "${member['property']}"}
                        },
                        %endfor
                        },
                        make_action(action::${event['action']['name']}(
                        %for i, p in enumerate(event['action']['parameters']):
                        %if (i+1) != len(event['action']['parameters']):
                            static_cast<${p['type']}>(${p['value']}),
                        %else:
                            static_cast<${p['type']}>(${p['value']})
                        %endif
                        %endfor
                        )),
                        std::vector<PropertyChange>{
                        %for s in event['signal']:
                            PropertyChange{
                                interface("org.freedesktop.DBus.Properties") +
                                member("PropertiesChanged") +
                                type::signal() +
                                path("${s['path']}") +
                                arg0namespace("${s['interface']}"),
                                make_handler(propertySignal<${s['type']}>(
                                    "${s['interface']}",
                                    "${s['property']}",
                                    handler::setProperty<${s['type']}>(
                                        "${s['member']}",
                                        "${s['property']}"
                                    )
                                ))
                            },
                        %endfor
                        }
                    },
                %endfor
                }
            },
        %endfor
        }
    },
%endfor
};
'''


def getEventsInZone(zone_num, events_data):
    """
    Constructs the event entries defined for each zone using the events yaml
    provided.
    """
    events = []

    if 'events' in events_data:
        for e in events_data['events']:
            for z in e['zone_conditions']:
                if zone_num not in z['zones']:
                    continue

            event = {}
            # Add set speed event group
            group = []
            groups = next(g for g in events_data['groups']
                          if g['name'] == e['group'])
            for member in groups['members']:
                members = {}
                members['type'] = groups['type']
                members['name'] = ("/xyz/openbmc_project/" +
                                   groups['type'] +
                                   member)
                members['interface'] = e['interface']
                members['property'] = e['property']['name']
                group.append(members)
            event['group'] = group

            # Add set speed action and function parameters
            action = {}
            actions = next(a for a in events_data['actions']
                           if a['name'] == e['action']['name'])
            action['name'] = actions['name']
            params = []
            for p in actions['parameters']:
                param = {}
                if type(e['action'][p]) is not dict:
                    if p == 'property':
                        param['value'] = str(e['action'][p]).lower()
                        param['type'] = str(e['property']['type']).lower()
                    else:
                        # Default type to 'size_t' when not given
                        param['value'] = str(e['action'][p]).lower()
                        param['type'] = 'size_t'
                    params.append(param)
                else:
                    param['value'] = str(e['action'][p]['value']).lower()
                    param['type'] = str(e['action'][p]['type']).lower()
                    params.append(param)
            action['parameters'] = params
            event['action'] = action

            # Add property change signal handler
            signal = []
            for path in group:
                signals = {}
                signals['path'] = path['name']
                signals['interface'] = e['interface']
                signals['property'] = e['property']['name']
                signals['type'] = e['property']['type']
                signals['member'] = path['name']
                signal.append(signals)
            event['signal'] = signal

            events.append(event)

    return events


def getFansInZone(zone_num, profiles, fan_data):
    """
    Parses the fan definition YAML files to find the fans
    that match both the zone passed in and one of the
    cooling profiles.
    """

    fans = []

    for f in fan_data['fans']:

        if zone_num != f['cooling_zone']:
            continue

        # 'cooling_profile' is optional (use 'all' instead)
        if f.get('cooling_profile') is None:
            profile = "all"
        else:
            profile = f['cooling_profile']

        if profile not in profiles:
            continue

        fan = {}
        fan['name'] = f['inventory']
        fan['sensors'] = f['sensors']
        fans.append(fan)

    return fans


def getConditionInZoneConditions(zone_condition, zone_conditions_data):
    """
    Parses the zone conditions definition YAML files to find the condition
    that match both the zone condition passed in.
    """

    condition = {}

    for c in zone_conditions_data['conditions']:

        if zone_condition != c['name']:
            continue
        condition['type'] = c['type']
        properties = []
        for p in c['properties']:
            property = {}
            property['property'] = p['property']
            property['interface'] = p['interface']
            property['path'] = p['path']
            property['type'] = p['type'].lower()
            property['value'] = str(p['value']).lower()
            properties.append(property)
        condition['properties'] = properties

        return condition


def buildZoneData(zone_data, fan_data, events_data, zone_conditions_data):
    """
    Combines the zone definition YAML and fan
    definition YAML to create a data structure defining
    the fan cooling zones.
    """

    zone_groups = []

    for group in zone_data:
        conditions = []
        # zone conditions are optional
        if 'zone_conditions' in group and group['zone_conditions'] is not None:
            for c in group['zone_conditions']:

                if not zone_conditions_data:
                    sys.exit("No zone_conditions YAML file but" +
                             "zone_conditions used in zone YAML")

                condition = getConditionInZoneConditions(c['name'],
                                                         zone_conditions_data)

                if not condition:
                    sys.exit("Missing zone condition " + c['name'])

                conditions.append(condition)

        zone_group = {}
        zone_group['conditions'] = conditions

        zones = []
        for z in group['zones']:
            zone = {}

            # 'zone' is required
            if ('zone' not in z) or (z['zone'] is None):
                sys.exit("Missing fan zone number in " + zone_yaml)

            zone['num'] = z['zone']

            zone['full_speed'] = z['full_speed']

            # 'cooling_profiles' is optional (use 'all' instead)
            if ('cooling_profiles' not in z) or \
                    (z['cooling_profiles'] is None):
                profiles = ["all"]
            else:
                profiles = z['cooling_profiles']

            fans = getFansInZone(z['zone'], profiles, fan_data)
            events = getEventsInZone(z['zone'], events_data)

            if len(fans) == 0:
                sys.exit("Didn't find any fans in zone " + str(zone['num']))

            zone['fans'] = fans
            zone['events'] = events
            zones.append(zone)

        zone_group['zones'] = zones
        zone_groups.append(zone_group)

    return zone_groups


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

    parser.add_argument('-z', '--zone_yaml', dest='zone_yaml',
                        default="example/zones.yaml",
                        help='fan zone definitional yaml')
    parser.add_argument('-f', '--fan_yaml', dest='fan_yaml',
                        default="example/fans.yaml",
                        help='fan definitional yaml')
    parser.add_argument('-e', '--events_yaml', dest='events_yaml',
                        help='events to set speeds yaml')
    parser.add_argument('-c', '--zone_conditions_yaml',
                        dest='zone_conditions_yaml',
                        help='conditions to determine zone yaml')
    parser.add_argument('-o', '--output_dir', dest='output_dir',
                        default=".",
                        help='output directory')
    args = parser.parse_args()

    if not args.zone_yaml or not args.fan_yaml:
        parser.print_usage()
        sys.exit(-1)

    with open(args.zone_yaml, 'r') as zone_input:
        zone_data = yaml.safe_load(zone_input) or {}

    with open(args.fan_yaml, 'r') as fan_input:
        fan_data = yaml.safe_load(fan_input) or {}

    events_data = {}
    if args.events_yaml:
        with open(args.events_yaml, 'r') as events_input:
            events_data = yaml.safe_load(events_input) or {}

    zone_conditions_data = {}
    if args.zone_conditions_yaml:
        with open(args.zone_conditions_yaml, 'r') as zone_conditions_input:
            zone_conditions_data = yaml.safe_load(zone_conditions_input) or {}

    zone_config = buildZoneData(zone_data.get('zone_configuration', {}),
                                fan_data, events_data, zone_conditions_data)

    manager_config = zone_data.get('manager_configuration', {})

    if manager_config.get('power_on_delay') is None:
        manager_config['power_on_delay'] = 0

    output_file = os.path.join(args.output_dir, "fan_zone_defs.cpp")
    with open(output_file, 'w') as output:
        output.write(Template(tmpl).render(zones=zone_config,
                     mgr_data=manager_config))
