<?xml version="1.0"?>

<project name="dotnet" basedir="." default="init">
  <property environment="env"/>
  <property name="build.dir" location="dotnet/build"/>
  <property name="src.dir" location="dotnet"/>

  <property name="out.csc" location="${src.dir}/out.cs"/>
  <property name="out.app" location="${build.dir}/out.exe"/>
  <property name="out.type" value="exe"/>

  <target name="probe_for_apps" >
   <condition property="ilasm.found">
      <or>
        <available file="ilasm"     filepath="${env.PATH}" />
        <available file="ilasm.exe" filepath="${env.PATH}" />
        <available file="ilasm.exe" filepath="${env.Path}" />
      </or>
    </condition>
   <echo> ilasm.found=${ilasm.found}</echo>
   <condition property="csc.found">
      <or>
        <available file="csc"     filepath="${env.PATH}" />
        <available file="csc.exe" filepath="${env.PATH}" />
        <available file="csc.exe" filepath="${env.Path}" />
      </or>
    </condition>
   <echo> csc.found=${csc.found}</echo>
   <!-- visual basic compiler -->
   <condition property="vbc.found">
      <or>
        <available file="vbc"     filepath="${env.PATH}" />
        <available file="vbc.exe" filepath="${env.PATH}" />
        <available file="vbc.exe" filepath="${env.Path}" />
      </or>
    </condition>
   <echo> vbc.found=${vbc.found}</echo>
   <!-- visual J# compiler -->
   <condition property="jsharp.found">
      <or>
        <available file="vjc"     filepath="${env.PATH}" />
        <available file="vjc.exe" filepath="${env.PATH}" />
        <available file="vjc.exe" filepath="${env.Path}" />
      </or>
    </condition>
   <echo> jsharp.found=${jsharp.found}</echo>

   <!-- Mono C# compiler -->
   <condition property="mcs.found">
      <available file="mcs"     filepath="${env.PATH}" />
    </condition>
   <echo> mcs.found=${mcs.found}</echo>

   <!-- any C# compiler -->
   <condition property="c#.found">
      <or>
        <isset property="csc.found"/>
        <isset property="mcs.found"/>
      </or>
   </condition>

   <!-- Mono's ilasm -->
   <condition property="mono.ilasm.found">
      <available file="ilasm"     filepath="${env.PATH}" />
    </condition>
   <echo> mono.ilasm.found=${mono.ilasm.found}</echo>

   <condition property="ildasm.found">
      <or>
        <available file="ildasm"     filepath="${env.PATH}" />
        <available file="ildasm.exe" filepath="${env.PATH}" />
        <available file="ildasm.exe" filepath="${env.Path}" />
      </or>
    </condition>
   <echo> ildasm.found=${ildasm.found}</echo>

   <condition property="dotnetapps.found">
      <or>
        <and>
          <isset property="mcs.found"/>
          <isset property="mono.ilasm.found"/>
        </and>
        <and>
          <isset property="csc.found"/>
<!--         <isset property="vbc.found"/> -->
          <isset property="ilasm.found"/>
        </and>
      </or>
    </condition>
   <echo> dotnetapps.found=${dotnetapps.found}</echo>

   <condition property="mono.executable" value="mono">
        <or>
          <available file="mono"     filepath="${env.PATH}" />
          <available file="mono.exe" filepath="${env.PATH}" />
        </or>
   </condition>
   <property name="mono.executable" value="mint"/>

   <!-- now set a prop of the compiler name to whatever we found --> 
   <condition property="cs.compiler" value="csc">
      <isset property="csc.found"/>
   </condition>   

   <condition property="cs.compiler" value="mcs">
      <isset property="mcs.found"/>
   </condition>   
   
  </target>

  <target name="init" depends="probe_for_apps">
    <mkdir dir="${build.dir}"/>
  </target>

  <target name="teardown">
    <delete dir="${build.dir}"/>
  </target>

  <target name="validate_csc" depends="init">
    <fail unless="c#.found">Needed C# compiler is missing</fail>
  </target>

  <target name="validate_ilasm" depends="init">
    <fail unless="ilasm.found">Needed ilasm is missing</fail>
  </target>

  <target name="validate_jsharp" depends="init">
    <fail unless="jsharp.found">No vjc on the path</fail>
  </target>


  <target name="testCSC" depends="testCSC-Mono,testCSC-MS"/>

  <target name="testCSC-MS" depends="validate_csc" if="csc.found">
    <property name="testCSC.exe"
      location="${build.dir}/ExampleCsc.exe" />
    <csc
      destFile="${testCSC.exe}"
      targetType="exe"
      srcDir="${src.dir}"
      >
    </csc>
    <available property="app.created" file="${testCSC.exe}"/>
    <fail unless="app.created">No app ${testCSC.exe} created</fail>
    <exec executable="${testCSC.exe}" failonerror="true" />
    <delete file="${testCSC.exe}"/>
  </target>

  <target name="testCSC-Mono" depends="validate_csc" if="mcs.found">
    <property name="testCSC.exe"
      location="${build.dir}/ExampleCsc.exe" />
    <csc
      destFile="${testCSC.exe}"
      targetType="exe"
      includedefaultreferences="true"
      srcDir="${src.dir}"
      >
    </csc>
    <available property="app.created" file="${testCSC.exe}"/>
    <fail unless="app.created">No app ${testCSC.exe} created</fail>
    <exec executable="${mono.executable}" failonerror="true">
      <arg value="${testCSC.exe}"/>
    </exec>
    <delete file="${testCSC.exe}"/>
  </target>

  <target name="testCSCintrinsicFileset"
          depends="testCSCintrinsicFileset-MS,testCSCintrinsicFileset-Mono"/>

  <target name="testCSCintrinsicFileset-MS" depends="validate_csc" if="csc.found">
    <property name="testCSC.exe"
      location="${build.dir}/ExampleCsc.exe"/>
    <csc
      destFile="${testCSC.exe}"
      targetType="exe"
      srcDir="${src.dir}"
      includes="**/*.cs"
      >
    </csc>
    <available property="app.created" file="${testCSC.exe}"/>
    <fail unless="app.created">No app ${testCSC.exe} created</fail>
    <exec executable="${testCSC.exe}" failonerror="true" />
    <delete file="${testCSC.exe}"/>
  </target>

  <target name="testCSCintrinsicFileset-Mono" depends="validate_csc" if="mcs.found">
    <property name="testCSC.exe"
      location="${build.dir}/ExampleCsc.exe"/>
    <csc
      destFile="${testCSC.exe}"
      targetType="exe"
      srcDir="${src.dir}"
      includes="**/*.cs"
      includedefaultreferences="true"
      >
    </csc>
    <available property="app.created" file="${testCSC.exe}"/>
    <fail unless="app.created">No app ${testCSC.exe} created</fail>
    <exec executable="${mono.executable}" failonerror="true">
      <arg value="${testCSC.exe}"/>
    </exec>
    <delete file="${testCSC.exe}"/>
  </target>

  <target name="testCSCdll" depends="testCSCdll-MS,testCSCdll-Mono"/>

  <target name="testCSCdll-MS" depends="validate_csc" if="csc.found">
    <property name="testCSC.dll"
      location="${build.dir}/Example2.dll" />
    <csc
      destFile="${testCSC.dll}"
      targetType="library"
      executable="csc"
      >
      <src dir="${src.dir}" includes="example2.cs"/>
    </csc>
    <available property="dll.created" file="${testCSC.dll}"/>
    <fail unless="dll.created">No file ${testCSC.dll} created</fail>
  </target>

  <target name="testCSCdll-Mono" depends="validate_csc" if="mcs.found">
    <property name="testCSC.dll"
      location="${build.dir}/Example2.dll" />
    <csc
      destFile="${testCSC.dll}"
      targetType="library"
      includedefaultreferences="true"
      >
      <src dir="${src.dir}" includes="example2.cs"/>
    </csc>
    <available property="dll.created" file="${testCSC.dll}"/>
    <fail unless="dll.created">No file ${testCSC.dll} created</fail>
  </target>

  <target name="testCscReferences"
    depends="testCscReferences-MS,testCscReferences-Mono"/>

  <target name="testCscReferences-MS" depends="validate_csc,testCSCdll-MS"
          if="csc.found">
    <property name="testCscReferences.exe"
      location="${build.dir}/ExampleCsc2.exe" />
    <csc
      destFile="${testCscReferences.exe}"
      targetType="exe"
      >
      <src file="${src.dir}/example.cs"/>
      <reference file="${testCSC.dll}" />
      <define name="RELEASE" />
      <define name="DEBUG" if="undefined.property"/>
      <define name="def3" unless="undefined.property"/>
    </csc>
    <available property="refapp.created" file="${testCscReferences.exe}"/>
    <fail unless="refapp.created">No app ${testCscReferences.exe} created</fail>
    <exec executable="${testCscReferences.exe}" failonerror="true" />
  </target>

  <target name="testCscReferences-Mono" depends="validate_csc,testCSCdll-Mono"
          if="mcs.found">
    <property name="testCscReferences.exe"
      location="${build.dir}/ExampleCsc2.exe" />
    <csc
      destFile="${testCscReferences.exe}"
      targetType="exe"
      includedefaultreferences="true"
      >
      <src file="${src.dir}/example.cs"/>
      <reference file="${testCSC.dll}" />
      <define name="RELEASE" />
      <define name="DEBUG" if="undefined.property"/>
      <define name="def3" unless="undefined.property"/>
    </csc>
    <available property="refapp.created" file="${testCscReferences.exe}"/>
    <fail unless="refapp.created">No app ${testCscReferences.exe} created</fail>
    <exec executable="${mono.executable}" failonerror="true">
      <arg value="${testCscReferences.exe}"/>
    </exec>
  </target>

  <target name="testILASM"
    depends="testILASM-Mono,testILASM-MS"
    if="ilasm.found"/>

  <target name="ilasm" depends="validate_ilasm" 
      if="ilasm.found">
    <property name="testILASM.exe"
      location="${build.dir}/ExampleIlasm.exe" />
    <ilasm
      destFile="${testILASM.exe}"
      targetType="exe"
      >
      <src dir="${src.dir}" includes="*.il"/>
    </ilasm>
    <available property="ilasm.created" file="${testILASM.exe}"/>
    <fail unless="ilasm.created">No app ${testILASM.exe} created</fail>
  </target>

    <target name="testILASM-MS" depends="ilasm" 
      if="ilasm.found" unless="mono.ilasm.found">
      <exec executable="${testILASM.exe}"
        failonerror="true"/>
    </target>

    <target name="testILASM-Mono" depends="ilasm" 
      if="mono.ilasm.found">
      <exec executable="${mono.executable}"
        failonerror="true">
        <arg value="${testILASM.exe}"/>
      </exec>
    </target>

  <!-- not including this in the test as it creates an exe in the src dir -->

  <target name="testIlasmNoDestFile"  depends="validate_ilasm">
    <ilasm
      targetType="exe"
      >
      <src dir="${src.dir}" includes="**/*.il"/>
    </ilasm>
  </target>

  <!-- just here to look at fileset refid conversion by hand -->
  <target name="echoFileset">
    <fileset id="ilasm" dir="${src.dir}" includes="**/*.il" />
    <property name="ilasm.string" refid="ilasm"/>
    <echo>${ilasm.string}</echo>
  </target>

  <target name="testILDASM"   depends="testILASM" if="ildasm.found">
    <property name="testILDASM.il"
      location="${build.dir}/ExampleIldasm.il" />
    <ildasm
      srcFile="${testILASM.exe}"
      destFile="${testILDASM.il}"
      metadata="true"
      header="true"
      linenumbers="true"
      encoding="ascii"
      />
    <available property="ildasm.created" file="${testILDASM.il}"/>
    <fail unless="ildasm.created">No file ${testILDASM.il} created</fail>
  </target>

  <!-- this is an error -->
  <target name="testILDASM_empty"   depends="validate_ilasm" >
    <ildasm/>
  </target>

  <target name="jsharp" depends="init" if="jsharp.found" >
    <property name="jsharp.exe"
      location="${build.dir}/jsharp.exe" />
    <jsharpc
        destFile="${jsharp.exe}"
        targetType="exe"
        >
      <src dir="${src.dir}" includes="*.java"/>
    </jsharpc>
    <exec executable="${jsharp.exe}" failonerror="true" />
  </target>

  <target name="testCSCresponseFile" depends="validate_csc" >
    <property name="testCSCresponseFile.exe"
      location="${build.dir}/testCSCresponseFile.exe" />
    <csc
      destFile="${testCSCresponseFile.exe}"
      targetType="exe"
      executable="${cs.compiler}"
      useResponseFile="true"
      srcDir="${src.dir}"
      >
    </csc>
    <available property="app.created" file="${testCSCresponseFile.exe}"/>
    <fail unless="app.created">No app ${testCSCresponseFile.exe} created</fail>
    <delete file="${testCSCresponseFile.exe}"/>
  </target>  


</project>

