<?xml version="1.0" encoding="UTF-8"?>
<project name="SonataCoreBundle" basedir="." default="build:main">

    <!-- Config files -->
    <property name="dir.config"                  value="${project.basedir}" />
    <property name="config.phpunit"              value="${dir.config}/phpunit.xml.dist" />
    <property name="config.pmd"                  value="${dir.config}/pmd.xml.dist" />

    <!-- Build paths -->
    <property name="dir.build"                   value="${project.basedir}/build" />
    <property name="dir.reports"                 value="${dir.build}/reports" />
    <property name="dir.reports.check"           value="${dir.reports}/check" />
    <property name="dir.reports.test"            value="${dir.reports}/test" />
    <property name="dir.reports.test.unit"       value="${dir.reports.test}/unit" />
    <property name="dir.reports.test.coverage"   value="${dir.reports.test}/coverage" />
    <property name="dir.docs"                    value="${dir.build}/docs" />
    <property name="dir.docs.api"                value="${dir.docs}/api" />
    <property name="dir.docs.rst"                value="${dir.docs}/rst" />
    <property name="dir.docs.php"                value="${dir.docs}/php" />

    <!-- Source paths -->
    <property name="dir.src"                     value="${project.basedir}" />
    <property name="dir.src.rst"                 value="${dir.src}/Resources/doc" />

    <!-- Source fileset (used by check tasks) -->
    <fileset id="sourcecode" dir="${dir.src}">
        <include name="**/*.php" />
        <exclude name="**/*Test.php" />
        <exclude name="vendor/**/*.php" />
    </fileset>


    <!-- BUILD TASKS -->

    <!-- Main (default) task -->
    <target name="build:main"
            depends="build:clean, build:prepare, build:check, build:test, build:doc"
            description="Run all test and build everything"/>

    <!-- Clean previous build files -->
    <target name="build:clean"
            description="Clean previous build files">

        <delete dir="${dir.build}" verbose="true" />

    </target>

    <!-- Prepare build (performed by each build:* task when called as standalone) -->
    <target name="build:prepare"
            description="Prepare build">

        <mkdir dir="${dir.build}" />

    </target>

    <!-- Check Project -->
    <target name="build:check"
            description="Check source code"
            depends="build:prepare, check:prepare, check:cs, check:md, check:cpd"/>

    <!-- Test Project -->
    <target name="build:test"
            description="Perform all tests"
            depends="build:prepare, test:prepare, test:unit"/>

    <!-- Generate documentation -->
    <target name="build:doc"
            depends="build:prepare, doc:prepare, doc:api"
            description="Generate API documentation"/>

    <!-- CHECK SECTION -->

    <!-- Prepare check (performed by each check:* task when called as standalone) -->
    <target name="check:prepare"
            description="Create check directories">

        <mkdir dir="${dir.reports.check}" />

    </target>

    <!-- CodeSniffer with Symfony2 convention -->
    <target name="check:cs"
            depends="check:prepare"
            description="Generate PHP_CodeSniffer report">

        <phpcodesniffer standard="Symfony2" showSniffs="true" showWarnings="true">
            <fileset refid="sourcecode" />
            <config name="error_severity"   value="1"/>
            <config name="warning_severity" value="5"/>
            <formatter type="checkstyle" outfile="${dir.reports.check}/checkstyle.xml" />
        </phpcodesniffer>

    </target>

    <!-- PHP Copy and Paste Detector -->
    <target name="check:cpd"
            description="Generate phpcpd report"
            depends="check:prepare">

        <phpcpd>
            <fileset refid="sourcecode" />
            <formatter type="pmd" outfile="${dir.reports.check}/cpd.xml" />
        </phpcpd>

    </target>

    <!-- PHP Mess detector -->
    <target name="check:md"
            description="Generate phpmd report"
            depends="check:prepare" >

        <!-- if config.pmd file not found, use default pmd config -->
        <if>
            <not><available file="${config.pmd}"/></not>
            <then>
                <echo msg="phpmd config file not found: ${config.pmd}" />
                <property name="config.pmd" value="codesize,unusedcode,naming,design" override="yes"/>
            </then>
        </if>

        <phpmd rulesets="${config.pmd}">
            <fileset refid="sourcecode" />
            <formatter type="xml" outfile="${dir.reports.check}/pmd.xml" />
        </phpmd>

    </target>

    <!-- TEST SECTION -->

    <!-- Prepare test environment (performed by each test:* task when called as standalone) -->
    <target name="test:prepare"
            description="Prepare the test environment">

        <echo msg="Prepare test report directory" />
        <mkdir dir="${dir.reports.test}" />

        <echo msg="Installing/Updating vendors..." />
        <exec command="composer update --dev" passthru="true"/>

    </target>

    <!-- Prepare unit test environment -->
    <target name="test:unit:prepare"
            description="Prepare the unit test environment"
            depends="test:prepare">

        <mkdir dir="${dir.reports.test.unit}" />

    </target>

    <!-- Execute unit tests and code coverage -->
    <target name="test:unit"
            description="Perform unit tests and code coverage"
            depends="test:prepare, test:unit:prepare">

        <exec executable="phpunit" logoutput="true">
            <arg line="--log-junit ${dir.reports.test.unit}/phpunit.xml" />
            <arg line="--coverage-clover ${dir.reports.test.coverage}/clover.xml" />
            <arg line="--coverage-html ${dir.reports.test.coverage}/html" />
            <arg line="-c ${config.phpunit}" />
        </exec>

    </target>

    <!-- DOCUMENTATION SECTION -->

    <!-- Prepare the documentation environment -->
    <target name="doc:prepare"
            description="Prepare the documentation">

        <mkdir dir="${dir.docs}" />

    </target>

    <!-- Prepare the Api documentation -->
    <target name="doc:api:prepare"
            description="Prepare the API documentation">

        <mkdir dir="${dir.docs.api}" />

    </target>

    <!-- Generate the Api documentation -->
    <target name="doc:api"
            description="Generate API documentation"
            depends="doc:prepare, doc:api:prepare">

        <exec executable="apigen" logoutput="true" passthru="true">
            <arg line="--source ${dir.src}" />
            <arg line="--exclude */vendor/*" />
            <arg line="--exclude */Tests/*" />
            <arg line="--destination ${dir.docs.api}" />
        </exec>

    </target>

    <!-- Prepare the phpDoc documentation -->
    <target name="doc:php:prepare"
            description="Prepare the Php documentation">

        <mkdir dir="${dir.docs.php}" />

    </target>

    <!-- Build the phpDoc documentation -->
    <target name="doc:php"
            description="Generate Php documentation"
            depends="doc:prepare, doc:php:prepare">

        <exec executable="phpdoc" logoutput="true" passthru="true">
            <arg line="--directory ${dir.src}" />
            <arg line="--ignore '*/vendor/*,*/Tests/*'" />
            <arg line="--target ${dir.docs.php}" />
            <arg line="--sourcecode" />

        </exec>

    </target>

    <!-- Generate the RST documentation -->
    <target name="doc:rst"
            description="Generate RST documentation"
            depends="doc:prepare">

        <!-- delete previous directory (sphinx refuses to work on an existing directory) -->
        <delete dir="${dir.docs.rst}"/>

        <exec command="sphinx-build -C -a -b html ${dir.src.rst} ${dir.docs.rst}" passthru="true" />

    </target>

</project>
