import org.activemq.openwire.tool.OpenWireScript

/**
 * Generates the C# marshalling code for the Open Wire Format
 *
 * @version $Revision: 1.1.1.1 $
 */
class GenerateCSharpClasses extends OpenWireScript {

    Object run() {
        def destDir = new File("target/generated/dotnet/cs/org/activemq/openwire")
        destDir.mkdirs()

        def messageClasses = classes.findAll { isMessageType(it) }

        println "Generating Java marshalling code to directory ${destDir}"

        def buffer = new StringBuffer()

        int counter = 0
        Map map = [:]

        for (jclass in messageClasses) {

            println "Processing $jclass.simpleName"

            def properties = jclass.declaredProperties.findAll { isValidProperty(it) }
            def file = new File(destDir, jclass.simpleName + ".cs")

            String baseClass = "AbstractPacket"
            if (jclass.superclass?.simpleName == "ActiveMQMessage") {
                baseClass = "ActiveMQMessage"
            }

            buffer << """
${jclass.simpleName}.class
"""

            file.withWriter { out |
                out << """/**
 * Marshalling code for Open Wire Format for ${jclass.simpleName}
 *
 *
 * NOTE!: This file is autogenerated - do not modify!
 *        if you need to make a change, please see the Groovy scripts in the
 *        activemq-openwire module
 */

using System;
using System.Collections;

namespace ActiveMQ
{
    public class ${jclass.simpleName} : $baseClass
    {
"""
                for (property in properties) {

                    def type = toCSharpType(property.type)
                    def name = decapitalize(property.simpleName)
                    out << """        $type $name;
"""
                }

                out << """


        // TODO generate Equals method
        // TODO generate HashCode method
        // TODO generate ToString method


        public overide int getPacketType() {
            return ${getEnum(jclass)};
        }


        // Properties

"""
                for (property in properties) {
                    def type = toCSharpType(property.type)
                    def name = decapitalize(property.simpleName)
                    def getter = property.getter.simpleName
                    def setter = property.setter.simpleName


                    out << """
        public $type $getter()
        {
            return this.$name;
        }

        public void $setter($type $name)
        {
              this.$name = $name;
        }

"""
                }

                out << """
    }
}
"""
            }
        }
    }

    def toCSharpType(type) {
        def name = type.qualifiedName
        switch (type) {
            case "java.lang.String":
                return "string"
            case "org.activemq.message.ActiveMQDestination":
                return "ActiveMQDestination"
            case "org.activemq.message.ActiveMQXid":
                return "ActiveMQXid"
            default:
                return name
        }
    }
}