#!/usr/bin/perl
# Generate typedefs and packages with destroy functions.

use strict;
use warnings;

my @types = qw(
    ApplicationDescription
    Boolean
    BrowseDescription
    BrowseNextRequest
    BrowseRequest
    BuildInfo
    Byte
    ByteString
    CreateMonitoredItemsRequest
    CreateSubscriptionRequest
    DataTypeAttributes
    DeleteMonitoredItemsRequest
    DeleteSubscriptionsRequest
    Double
    ExpandedNodeId
    Int32
    LocalizedText
    MessageSecurityMode
    ModifySubscriptionRequest
    MonitoredItemCreateRequest
    NodeClass
    NodeId
    ObjectAttributes
    ObjectTypeAttributes
    QualifiedName
    ReadRequest
    ReadValueId
    ReferenceTypeAttributes
    SetPublishingModeRequest
    String
    UInt32
    VariableAttributes
    VariableTypeAttributes
    Variant
    ViewAttributes
    WriteValue
);

open(my $tf, '>', "Open62541-typedef.xsh")
    or die "Open 'Open62541-typedef.xsh' for writing failed: $!";
print $tf "/* begin generated by $0 */\n\n";
open(my $pf, '>', "Open62541-destroy.xsh")
    or die "Open 'Open62541-destroy.xsh' for writing failed: $!";
print $pf "# begin generated by $0\n\n";

foreach my $type (sort @types) {
    print_xstypedef($tf, $type);
    print_xspackage($pf, $type);
}

print $tf "\n/* end generated by $0 */\n";
close($tf)
    or die "Close 'Open62541-typedef.xsh' after writing failed: $!";
print $pf "# end generated by $0\n";
close($pf)
    or die "Close 'Open62541-destroy.xsh' after writing failed: $!";

exit(0);

########################################################################
sub print_xstypedef {
    my ($xsf, $type) = @_;
    print $xsf <<"EOXSTDEF";
typedef UA_$type *		OPCUA_Open62541_$type;
EOXSTDEF
}

########################################################################
sub print_xspackage {
    my ($xsf, $type) = @_;
    (my $var = $type) =~ s/^./lc($&)/e;
    $var =~ s/^double$/double_/;  # double is a C keyword
    print $xsf "MODULE = OPCUA::Open62541\t";
    print $xsf "PACKAGE = OPCUA::Open62541::$type\t";
    print $xsf "PREFIX = UA_${type}_\n\n";
    print $xsf <<"EOXSPACK";
void
UA_${type}_DESTROY($var)
	OPCUA_Open62541_${type}	$var
    CODE:
	DPRINTF("$var %p", $var);
	UA_${type}_delete($var);

EOXSPACK
}
