// Simple demo code to print out a signal tree using the
// code generated by vspec2c.py code
//
#include "signal_spec.h"
#include "signal_macro.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// Recursively print out sig and all its children.
void print_signal(const vss_signal_t * sig, int indent)
{
    printf("%*sName:        %s\n", indent, "", sig->name);
    printf("%*sUUID:        %s\n", indent, "", sig->uuid);
    printf("%*sSignature:   0x%X\n", indent, "", sig->signature);
    printf("%*sDescription: %s\n", indent, "", sig->description);
    printf("%*sType:        %s\n", indent, "", vss_element_type_string(sig->element_type));

    // Print data type if this is not a branch
    if (sig->element_type != VSS_BRANCH)
        printf("%*sData Type:   %s\n", indent, "", vss_data_type_string(sig->data_type));

    // Print sensor type, if defined
    if (sig->sensor[0] != 0)
        printf("%*ssensor:      %s\n", indent, "", sig->sensor);

    // Print actuator type, if defined
    if (sig->actuator[0] != 0)
        printf("%*sactuator:    %s\n", indent, "", sig->actuator);


    // Check if we have a define min_val
    if (sig->min_val.i != VSS_LIMIT_UNDEFINED) {
        // Print out the right union member
        if (sig->data_type == VSS_FLOAT ||
            sig->data_type == VSS_DOUBLE)
            printf("%*smin_val:     %f\n", indent, "", sig->min_val.d);
        else
            printf("%*smin_val:     %ld\n", indent, "", sig->min_val.i);
    }

    // Check if we have a define max_val
    if (sig->max_val.i != VSS_LIMIT_UNDEFINED) {
        // Print out the right union member
        if (sig->data_type == VSS_FLOAT ||
            sig->data_type == VSS_DOUBLE)
            printf("%*smax_val:     %f\n", indent, "", sig->max_val.d);
        else
            printf("%*smax_val:     %ld\n", indent, "", sig->max_val.i);
    }


    // If we have an array of allowed enumeration values,
    // print them out.
    if (sig->enum_values[0] != 0) {
        int ind = 0;
        printf("%*senum:        ", indent, "");
        while(sig->enum_values[ind]) {
            printf("%s ", sig->enum_values[ind]);
            ind++;
        }
        puts("");
    }

    // Recursively print out the children with
    // the right indentation.
    if (sig->element_type == VSS_BRANCH) {
        int ind = 0;
        printf("%*schildren:" ,indent, "");
        while(sig->children[ind]) {
            print_signal(sig->children[ind], indent + 2);
            ind++;
            if (sig->children[ind])
                puts("");

        }
        printf("%*s---\n\n", indent, "");
    }

}

int main(int argc, char* argv[])
{
    vss_signal_t * sig = 0;
    int res = 0;
    char path[1024];

    // Dump the entire tree, starting with the root.
    print_signal(&vss_signal[0], 0);

    // Grab
    puts("Retrieving Vehicle.VehicleIdentification.VIN by its path");
    if ((res = vss_get_signal_by_path("Vehicle.VehicleIdentification.VIN", &sig))) {
        perror("vss_find_signal_by_path(\"Vehicle.VehicleIdentification.VIN\")");
        exit(255);
    }
    print_signal(sig, 0);

    puts("\n\nRetrieving Vehicle.Body.Mirrors.Left.Heating.Status by its macro.");
    // Picked up from vss_generated_macro.h
    sig = VSS_Vehicle_Body_Mirrors_Left_Heating_Status();

    if (!sig) {
        puts("Could not resolve a path string to signal for Mirror heating status");
        exit(255);
    }

    print_signal(sig, 0);

    puts("\n");
    printf("Signal path for Vehicle.Body.Mirrors.Left.Heating.Status is:\n");
    printf("                %s\n", vss_get_signal_path(sig, path, sizeof(path)));

    if (strcmp(path, "Vehicle.Body.Mirrors.Left.Heating.Status")) {
        puts("Incorrect path retrieved for Vehicle.Body.Mirrors.Left.Heating.Status");
        exit(255);
    }

    puts("\n");
    printf("Truncated path for Vehicle.Body.Mirrors.Left.Heating.Status is:\n");
    printf("                   %s\n", vss_get_signal_path(sig, path, 16));

    if (strcmp(path, "Vehicle.Body.")) {
        puts("Incorrect truncated retrieved for Vehicle.Body.Mirrors.Left.Heating.Status");
        puts("Wanted Vehicle.Body.");
        exit(255);
    }



    printf("\n\nSignature for Vehicle.Body.Mirrors.Left.Heating.Status: 0x%X\n", sig->signature);



    puts("\n\nRetrieving Vehicle.Body.Mirrors.Left.Heating.Status by its macro.");
    printf("\n\nVSS spec signature is: 0x%X\n", vss_get_signature());
    exit(0);
}
