<!--
  File: build.xml
  SPDX-License-Identifier: Unlicense
-->

<project xmlns:ivy="antlib:org.apache.ivy.ant"
    name="Project" default="all" basedir=".">

    <description>
        Ant build-file.
    </description>

    <property file="build.properties"/>

    <!-- ==================== PROPERTIES ==================== -->

    <!-- Project Directories -->
    <property name="src.dir"            location="src"/>
    <property name="main.dir"           location="${src.dir}/main"/>
    <property name="main-src.dir"       location="${main.dir}/java"/>
    <property name="main-resources.dir" location="${main.dir}/resources"/>
    <property name="build.dir"          location="target"/>
    <property name="log.dir"            location="${build.dir}/logs"/>
    <property name="build-main.dir"     location="${build.dir}/main"/>
    <property name="main-classes.dir"   location="${build-main.dir}/classes"/>
    <property name="test.dir"           location="${src.dir}/test"/>
    <property name="test-src.dir"       location="${test.dir}/java"/>
    <property name="test-resources.dir" location="${test.dir}/resources"/>
    <property name="build-test.dir"     location="${build.dir}/test"/>
    <property name="test-classes.dir"   location="${build-test.dir}/classes"/>
    <property name="lib.dir"            location="lib"/>

    <!-- Compiler Properties -->
    <fileset id="main.libs" dir="${lib.dir}">
        <exclude name="**/common-math*.jar,**/junit*.jar,**/hamcrest-core*.jar"/>
    </fileset>
    <path id="main.classpath">
        <pathelement location="${main-classes.dir}"/>
        <fileset refid="main.libs"/>
    </path>

    <!-- Ivy Properties -->
    <!-- https://repo1.maven.org/maven2/org/apache/ivy/ivy/2.5.0/ -->
    <property name="ivy-get.src"
        value="https://org/apache/ivy/ivy/${ivy.version}/ivy-${ivy.version}.jar"/>
    <property name="ivy-get.dest" value="${build.dir}/ivy.jar"/>

    <!-- Package Properties -->
    <property name="jar.filename-prefix"       value="${ant.project.name}-${project.version}"/>
    <property name="jar.dest-filename"         value="${jar.filename-prefix}.jar"/>
    <property name="jar.dest-fqfn"             value="${build.dir}/${jar.dest-filename}"/>
    <property name="jar.all-filename"          value="${jar.filename-prefix}-all.jar"/>
    <property name="jar.all-fqfn"              value="${build.dir}/${jar.all-filename}"/>

    <!-- Test Properties -->
    <fileset id="test.libs" dir="${lib.dir}"/>
    <path id="test.classpath">
        <pathelement location="${main-classes.dir}"/>
        <pathelement location="${test-classes.dir}"/>
        <fileset refid="test.libs"/>
    </path>

    <!-- ==================== TARGETS ==================== -->

    <!-- =============== activate-ivy =============== -->
    <target name="activate-ivy" depends="download-ivy">
        <path id="ivy-lib.path">
            <fileset dir="${build.dir}" includes="*.jar"/>
        </path>
        <taskdef resource="org/apache/ivy/ant/antlib.xml"
            uri="antlib:org.apache.ivy.ant"
            classpathref="ivy-lib.path"/>
    </target>

    <!-- =============== all =============== -->
    <target name="all" depends="build"
        description="Compiles, tests, and packages the project.">
    </target>

    <!-- =============== build =============== -->
    <target name="build" depends="jar"
        description="Packages the class files and any resources into an executable JAR.">

        <!--Expand the non-transitive JARs into build/temp -->
<!--
        <mkdir dir="${build.dir}/temp"/>
        <unzip dest="${build.dir}/temp"
            overwrite="true">
            <zipfileset dir="${lib.dir}">
                <exclude name="**/common-math*.jar"/>
                <exclude name="**/lombok*.jar"/>
                <exclude name="**/junit*.jar"/>
                <exclude name="**/hamcrest-core*.jar"/>
                <exclude name="**/*javadoc*"/>
                <exclude name="**/*sources*"/>
            </zipfileset>
        </unzip>
-->

        <!-- Expand the project JAR into build/temp -->
        <unzip src="${jar.dest-fqfn}"
            dest="${build.dir}/temp"
            overwrite="true">
        </unzip>

        <!-- Remove cruft -->
        <delete>
            <fileset dir="${build.dir}/temp/META-INF"/>
                <!--            <fileset dir="${build.dir}/temp/OSGI-OPT"/> -->
            <fileset dir="${build.dir}/temp" includes="LICENSE"/>
            <fileset dir="${build.dir}/temp" includes="NOTICE"/>
            <fileset dir="${build.dir}/temp" includes="*.html"/>
        </delete>

        <!-- Create the executable JAR file -->
        <jar destfile="${jar.all-fqfn}"
            basedir="${build.dir}/temp"
            compress="${jar.compress}"
            duplicate="${jar.duplicate}"
            index="${jar.index}"
            indexMetaInf="${jar.index-meta-inf}">
            <manifest>
                <attribute name="Main-Class" value="${project.main-class}"/>
            </manifest>
        </jar>

<!--
        <chmod file="${jar.all-fqfn}"
            perm="ug+x"/>
        <delete dir="build/temp"/>
-->
    </target>

    <!-- =============== clean =============== -->
    <target name="clean"
        description="Removes generated class files.">
        <delete dir="${build-main.dir}"/>
        <delete dir="${build-test.dir}"/>
    </target>

    <!-- =============== clobber =============== -->
    <target name="clobber"
        description="Deletes the build directory.">
        <delete dir="${build.dir}"/>
    </target>

    <!-- =============== compile =============== -->
    <target name="compile" depends="compile-main,compile-tests"
        description="Compiles the main and test source code."/>

    <!-- =============== compile-main =============== -->
    <target name="compile-main" depends="init"
        description="Compiles the main source code.">
        <javac srcdir="${main-src.dir}"
            destdir="${main-classes.dir}"
            source="${javac.source}"
            target="${javac.target}"
            deprecation="${javac.deprecation}"
            includeantruntime="${javac.ant-runtime}"
            fork="${javac.fork}"
            listfiles="${javac.list-files}">
            <classpath refid="main.classpath"/>
        </javac>
    </target>

    <!-- =============== compile-tests =============== -->
    <target name="compile-tests" depends="compile-main"
        description="Compiles the test source code.">
        <javac srcdir="${test-src.dir}"
            destdir="${test-classes.dir}"
            source="${javac.source}"
            target="${javac.target}"
            deprecation="${javac.deprecation}"
            includeantruntime="${javac.ant-runtime}"
            fork="${javac.fork}"
            listfiles="${javac.list-files}">
            <classpath refid="test.classpath"/>
        </javac>
    </target>

    <!-- =============== download-dependencies =============== -->
    <target name="download-dependencies" depends="activate-ivy"
        description="Downloads JAR dependencies.">
        <ivy:retrieve/>
    </target>

    <!-- =============== download-ivy =============== -->
    <target name="download-ivy" depends="init-dirs">
        <get src="${ivy-get.src}"
            dest="${ivy-get.dest}"
            verbose="${ivy-get.verbose}"
            ignoreerrors="${ivy-get.ignore-errors}"
            usetimestamp="${ivy-get.use-timestamp}"/>
    </target>

    <!-- =============== init =============== -->
    <target name="init" depends="init-dirs,download-dependencies"/>

    <!-- =============== init-dirs =============== -->
    <target name="init-dirs"
        description="Creates the project directory structure.">
        <mkdir dir="${main-src.dir}"/>
        <mkdir dir="${main-resources.dir}"/>
        <mkdir dir="${main-classes.dir}"/>
        <mkdir dir="${test-src.dir}"/>
        <mkdir dir="${test-resources.dir}"/>
        <mkdir dir="${test-classes.dir}"/>
        <mkdir dir="${log.dir}"/>
        <mkdir dir="${build.dir}"/>
        <mkdir dir="${lib.dir}"/>
    </target>

    <!-- =============== jar =============== -->
    <target name="jar" depends="test">

        <!-- Copy any resources and files into the main classes directory -->
        <copy todir="${main-classes.dir}"
            preservelastmodified="${copy.preserve-modified}"
            overwrite="${copy.overwrite}"
            force="${copy.force}"
            flatten="${copy.flatten}"
            includeemptydirs="{copy.include-empty-init-dirs}">
            <fileset dir="${main-resources.dir}"/>
        </copy>
        <copy todir="${main-classes.dir}"
            preservelastmodified="${copy.preserve-modified}"
            overwrite="${copy.overwrite}"
            force="${copy.force}"
            flatten="${copy.flatten}"
            includeemptydirs="{copy.include-empty-init-dirs}">
            <fileset file="COPYING"/>
        </copy>
        <copy todir="${main-classes.dir}"
            preservelastmodified="${copy.preserve-modified}"
            overwrite="${copy.overwrite}"
            force="${copy.force}"
            flatten="${copy.flatten}"
            includeemptydirs="{copy.include-empty-init-dirs}">
            <fileset file="README.md"/>
        </copy>

        <!-- Now create a JAR of the main classes directory -->
        <jar destfile="${jar.dest-fqfn}"
            basedir="${main-classes.dir}"
            compress="${jar.compress}"
            duplicate="${jar.duplicate}"
            index="${jar.index}"
            indexMetaInf="${jar.index-meta-inf}">
        </jar>
    </target>

    <!-- =============== run =============== -->
    <target name="run" depends="build"
        description="Creates and executes the executable JAR.">
        <java jar="${jar.all-fqfn}" fork="${java.fork}"/>
    </target>

    <!-- =============== test =============== -->
    <target name="test" depends="compile-tests"
        description="Runs JUnit tests of the projects main Java files.">
        <junit printsummary="${test.print-summary}"
            fork="${test.fork}"
            forkmode="${test.fork-mode}"
            haltonerror="${test.halt-on-error}"
            haltonfailure="${test.halt-on-failure}"
            includeantruntime="${test.include-ant-runtime}"
            showoutput="yes">
            <classpath refid="test.classpath"/>
            <formatter type="${test.formatter}"/>
            <batchtest todir="${log.dir}">
                <fileset dir="${test-src.dir}">
                    <include name="**/*Test*.java"/>
                </fileset>
            </batchtest>
        </junit>
    </target>
</project>
