<?xml version="1.0" encoding="UTF-8"?>

<project name="Orchard" default="build-jenkins"
    xmlns:if="ant:if" xmlns:unless="ant:unless">
    <property name="exclusionlist"
              value="library/Bootstrap,library/Cron,library/GoogleApi,library/Html5,library/Ioda,library/Web/Analytics,library/Web/Accounting,library/Web/Stomp,public,vendor,frontend,vagrant_boxes"/>
    <property name="exclusionlistwithslashes"
              value="library/Bootstrap/,library/Cron/,library/GoogleApi/,library/Html5/,library/Ioda/,library/Web/Analytics/,library/Web/Stomp/,public/,vendor/,frontend/,vagrant_boxes/"/>

    <property name="configsdir" value="${basedir}/application/configs"/>
    <property name="tempconfigsdir" value="${basedir}/build/tmp/configs"/>
    <property name="publicdir" value="${basedir}/public"/>
    <property name="temppublicdir" value="${basedir}/build/tmp/public"/>
    <property name="vhostdir" value="${basedir}/docker"/>
    <property name="tempvhostdir" value="${basedir}/build/tmp/docker"/>

    <property name="testFilter" value=""/>
    <property name="skipLint" value=""/>
    <property name="skipCoverage" value=""/>

    <target name="get-php-bin" description="Find out where php binary is">
        <exec executable="/usr/bin/which" outputProperty="php-bin">
            <arg value="php"/>
        </exec>
    </target>

    <target name="build-pr"
            depends="prepare,sequentialTasks"/>

    <target name="build-functional-tests"
            depends="prepare,phpunit-functional"/>

    <target name="build-jenkins"
            depends="prepare,sequentialTasks"/>

    <target name="clean" description="Cleanup build artifacts">
        <delete dir="${basedir}/build/api"/>
        <delete dir="${basedir}/build/code-browser"/>
        <delete dir="${basedir}/build/coverage"/>
        <delete dir="${basedir}/build/logs"/>
        <delete dir="${tempconfigsdir}"/>
        <delete dir="${temppublicdir}"/>
        <delete dir="${tempvhostdir}"/>
    </target>

    <target name="prepare" depends="clean" description="Prepare for build">
        <mkdir dir="${basedir}/build/api"/>
        <mkdir dir="${basedir}/build/code-browser"/>
        <mkdir dir="${basedir}/build/coverage"/>
        <mkdir dir="${basedir}/build/logs"/>
        <mkdir dir="${tempconfigsdir}"/>
        <mkdir dir="${temppublicdir}"/>
        <mkdir dir="${tempvhostdir}"/>
    </target>

    <target name="lint-parallel">
        <exec executable="${basedir}/vendor/bin/parallel-lint" failonerror="true">
            <arg line='${basedir}'/>
            <arg line='-e php,phtml,inc' />
            <arg line='--short' />
            <arg line='--exclude ${basedir}/library/GoogleApi/'/>
            <arg line='--exclude ${basedir}/vendor/'/>
            <arg line='--exclude ${basedir}/library/Ioda/'/>
            <arg line='--exclude ${basedir}/library/Html5/'/>
            <arg line='--exclude ${basedir}/library/Cron/'/>
            <arg line='--exclude ${basedir}/library/Bootstrap/'/>
            <arg line='--exclude ${basedir}/public/amfphp/'/>
            <arg line='--exclude ${basedir}/public/includes/phpchart/'/>
            <arg line='--exclude ${basedir}/public/includes/xmlchart/'/>
        </exec>
    </target>

    <target name="phpunit" description="Run unit tests with PHPUnit">
        <exec executable="${basedir}/vendor/bin/phpunit" dir="${basedir}/tests" failonerror="true">
            <arg value="--coverage-html" unless:true="${skipCoverage}"/>
            <arg value="${basedir}/build/coverage" unless:true="${skipCoverage}"/>
            <arg value="--coverage-clover" unless:true="${skipCoverage}"/>
            <arg value="${basedir}/build/logs/phpunit.coverage.xml" unless:true="${skipCoverage}"/>
            <arg value="--log-junit"/>
            <arg value="${basedir}/build/logs/phpunit.xml"/>
            <arg value="--filter" unless:blank="${testFilter}"/>
            <arg value="${testFilter}" unless:blank="${testFilter}"/>
            <arg value="--testsuite"/>
            <arg value="Orchard"/>
        </exec>
    </target>

    <target name="phpunit-functional" description="Run Functional tests with PHPUnit">
        <exec executable="${basedir}/vendor/bin/phpunit" dir="${basedir}/tests" failonerror="true">
            <arg value="--coverage-html" unless:true="${skipCoverage}"/>
            <arg value="${basedir}/build/coverage" unless:true="${skipCoverage}"/>
            <arg value="--coverage-clover" unless:true="${skipCoverage}"/>
            <arg value="${basedir}/build/logs/phpunit.coverage.xml" unless:true="${skipCoverage}"/>
            <arg value="--log-junit"/>
            <arg value="${basedir}/build/logs/functional/phpunit.xml"/>
            <arg value="--testsuite"/>
            <arg value="OrchardFunctional"/>
        </exec>
    </target>

    <target name="sequentialTasks" description="Run code analysis tasks in sequence">
        <antcall target="lint-parallel" unless:true="${skipLint}"/>
        <antcall target="phpcs" unless:true="${skipLint}"/>
        <antcall target="phpunit"/>
        <antcall target="rake"/>
    </target>

    <target name="phpcs" description="Find coding standard violations using PHP_CodeSniffer">
        <exec executable="${basedir}/vendor/bin/phpcs" failonerror="false">
            <arg value="--extensions=php,inc"/>
            <arg value="-p"/>
            <arg value="-n"/>
            <arg value="--report=checkstyle"/>
            <arg value="--report-file=${basedir}/build/logs/checkstyle.xml"/>
            <arg value="--standard=PSR2"/>
            <arg value="--ignore=${exclusionlist}"/>
            <arg path="${basedir}"/>
        </exec>
    </target>

    <target name="rake" description="Mocha tests">
        <exec executable="rake" failonerror="true" dir="${basedir}/frontend/">
            <arg value="jenkins:pr"/>
        </exec>
    </target>

    <target name="build-static-files" description="Build Static Files">
        <exec executable="rake" failonerror="true" dir="${basedir}/frontend/">
            <arg value="jenkins:build_static_files"/>
        </exec>
    </target>

    <!-- the reason for the complicated copying logic is to avoid invalidating docker cache; we don't want to touch files if we are just going to overwrite them with the exact same contents -->
    <target name="replace-configs" depends="prepare" description="Replace tokens in config files with values suitable for local development in Docker">
        <!-- copy shadow files to temp dir, to non-shadow file ext -->
        <copy todir="${tempconfigsdir}">
            <fileset dir="${configsdir}" includes="*.shadow.*" excludes="docker.shadow.properties" />
            <regexpmapper from="^(.*)\.shadow\.(.*)$$" to="\1.\2"/>
        </copy>
        <!-- perform token replacement -->
        <replace dir="${tempconfigsdir}" replacefilterfile="${configsdir}/docker.properties" summary="true" includes="*.*" excludes="*.shadow.*,*.properties" />
        <!-- copy config files from temp dir to original location, if changed -->
        <copy todir="${configsdir}">
            <fileset dir="${tempconfigsdir}" includes="*.*">
                <different targetdir="${configsdir}" ignoreFileTimes="true" ignoreContents="false" />
            </fileset>
        </copy>

        <!-- same thing for /public directory -->
        <!-- and .htaccess -->
        <copy file="${publicdir}/.dev.shadow.htaccess" tofile="${temppublicdir}/.htaccess"/>
        <!-- perform token replacement -->
        <replace dir="${temppublicdir}" replacefilterfile="${configsdir}/docker.properties" summary="true" includes="*.*" />
        <!-- copy config files from temp dir to original location, if changed -->
        <copy todir="${publicdir}">
            <fileset dir="${temppublicdir}" includes="*.*">
                <different targetdir="${publicdir}" ignoreFileTimes="true" ignoreContents="false" />
            </fileset>
        </copy>

        <!-- perform token replacement -->
        <replace dir="${tempvhostdir}" replacefilterfile="${configsdir}/docker.properties" summary="true" includes="*.*" />
        <!-- copy config files from temp dir to original location, if changed -->
        <copy todir="${vhostdir}">
            <fileset dir="${tempvhostdir}" includes="*.*">
                <different targetdir="${vhostdir}" ignoreFileTimes="true" ignoreContents="false" />
            </fileset>
        </copy>
    </target>
</project>
