<?xml version="1.0"?>

<!DOCTYPE project [
       <!ENTITY base SYSTEM "src/build/java/base.xml">
]>

<project default="usage" name="metrics-web" basedir="."
         xmlns:ivy="antlib:org.apache.ivy.ant">

  <property name="javadoc-title" value="MetricsWeb API Documentation"/>
  <property name="implementation-title" value="metrics-web" />
  <property name="release.version" value="1.3.0-dev" />
  <property name="metricslibversion" value="2.10.0" />
  <property name="exoneratorversion" value="4.3.0" />
  <property name="jetty.version" value="-9.2.21.v20170120" />
  <property name="warfile"
            value="metrics-web-${release.version}.war"/>

  <property name="name" value="metrics-web"/>

  <property name="project-main-class"
            value="org.torproject.metrics.stats.main.Main" />
  <property name="jarincludes" value="logback.xml" />
  <property name="additional2sign" value="${warfile}" />
  <property name="tardepends" value="war" />

  <property name="Rsources" value="${basedir}/src/main/R" />

  <property name="specdir" value="${basedir}/generated/spec" />

  <!-- The coverage needs to be improved! -->
  <target name="coverage-check">
    <cobertura-check totallinerate="0" totalbranchrate="0" >
      <!-- example regexes
      <regex pattern="org.torproject.abc.xyz.*"
             branchrate="87" linerate="73"/>
      -->
    </cobertura-check>
  </target>

  <patternset id="common" >
    <include name="commons-codec-1.10.jar"/>
    <include name="commons-lang3-3.5.jar"/>
    <include name="commons-math3-3.6.1.jar"/>
    <include name="jackson-annotations-2.8.6.jar"/>
    <include name="jackson-core-2.8.6.jar"/>
    <include name="jackson-databind-2.8.6.jar"/>
    <include name="logback-core-1.1.9.jar" />
    <include name="logback-classic-1.1.9.jar" />
    <include name="REngine-2.1.0.jar"/>
    <include name="Rserve-1.8.1.jar"/>
    <include name="slf4j-api-1.7.22.jar"/>
  </patternset>

  <patternset id="library" >
    <patternset refid="common" />
    <include name="metrics-lib-${metricslibversion}-thin.jar"/>
    <include name="commons-compress-1.13.jar"/>
    <include name="commons-math3-3.6.1.jar"/>
    <include name="postgresql-42.2.5.jar"/>
    <include name="javax.servlet-api-3.1.0.jar"/>
    <include name="xz-1.6.jar"/>
  </patternset>

  <patternset id="web" >
    <include name="exonerator-${exoneratorversion}-thin.jar" />
    <include name="jetty-annotations${jetty.version}.jar"/>
    <include name="jetty-server${jetty.version}.jar"/>
    <include name="jetty-servlet${jetty.version}.jar"/>
    <include name="jetty-util${jetty.version}.jar"/>
    <include name="jetty-http${jetty.version}.jar"/>
    <include name="jetty-io${jetty.version}.jar"/>
    <include name="jetty-xml${jetty.version}.jar"/>
    <include name="jetty-webapp${jetty.version}.jar"/>
    <include name="jetty-continuation${jetty.version}.jar"/>
    <include name="jetty-security${jetty.version}.jar"/>
  </patternset>

  <patternset id="webruntime" >
    <include name="asm-5.0.1.jar" />
    <include name="asm-commons-5.0.1.jar" />
    <include name="commons-compress-1.13.jar"/>
    <include name="jetty-plus${jetty.version}.jar"/>
    <include name="jetty-jndi${jetty.version}.jar"/>
    <include name="apache-jsp${jetty.version}.jar" />
    <include name="metrics-lib-${metricslibversion}-thin.jar"/>
    <include name="taglibs-standard-spec-1.2.5.jar"/>
    <include name="tomcat-embed-jasper-8.5.14.jar" />
    <include name="tomcat-embed-el-8.5.14.jar" />
    <include name="tomcat-embed-core-8.5.14.jar" />
    <include name="ecj-4.6.1.jar" />
  </patternset>

  <patternset id="runtime" >
    <patternset refid="library" />
    <patternset refid="web" />
  </patternset>

  <!-- Tasks for database testing. -->
  <target name="test-all-dbs"
          depends="init"
          description="Run all available database pgTAP tests." >
    <antcall target="test-db">
      <param name="db2test" value="servers" />
    </antcall>
    <antcall target="test-db">
      <param name="db2test" value="userstats" />
    </antcall>
  </target>

  <target name="test-db" description="A helper task for task test-all-dbs." >
    <property name="dbtestlog" value="${basedir}/${generated}/${db2test}-sql-test.txt" />
    <exec executable="psql"
          dir="${generated}"
          failonerror="false" >
      <arg value="--output=${dbtestlog}" />
      <arg value="--log-file=${basedir}/${generated}/all-dbs-test.log" />
      <arg value="--quiet" />
      <arg value="--file=${basedir}/src/test/sql/${db2test}/test-${db2test}.sql" />
      <arg value="--dbname=${db2test}"/>
    </exec>
    <exec executable="grep" outputproperty="dbtestresult"
          dir="${generated}"
          failonerror="false" >
      <arg value="failed" />
      <arg value="${dbtestlog}" />
    </exec>
    <fail message="${dbtestresult} see ${dbtestlog} for details." >
      <condition>
        <not>
          <length string="${dbtestresult}"
                  length="0" />
        </not>
      </condition>
    </fail>
    <echo message="Tests for ${db2test} passed." />
  </target>

  <!-- Create a .war file for deployment. -->
  <target name="war"
          depends="submoduleupdate,jar">

    <antcall target="generate-ml-javadoc" />

    <war destfile="${dist}/${warfile}"
         webxml="${resources}/web.xml"
	       basedir="${classes}">
      <restrict>
        <not>
          <and>
            <name name="META-INF/*" />
            <not>
              <name name="META-INF/services/*" />
            </not>
          </and>
        </not>
        <archives>
          <zips>
            <fileset dir="${libs}">
              <patternset refid="common" />
              <patternset refid="web" />
              <patternset refid="webruntime" />
            </fileset>
          </zips>
        </archives>
      </restrict>
      <exclude name="**/Test*.class" />
      <zipfileset dir="${buildresources}"
                  prefix=""
                  includes="logback.xml" />
      <zipfileset dir="${resources}/web"
                  prefix=""
                  includes="css/* images/** js/** fonts/** templates/** json/countries.topo.json" />
      <zipfileset dir="${resources}/web/jsps"
                  prefix="WEB-INF"
                  includes="*.jsp"/>
      <zipfileset dir="${resources}"
                  includes="*.properties" />
      <fileset dir="${resources}" includes="jetty.xml" />

      <zipfileset dir="${resources}/web/json"
                  prefix="WEB-INF/json"
                  includes="metrics.json categories.json news.json"/>

      <zipfileset dir="${resources}/web/properties"
                  includes="*.properties"/>

      <zipfileset dir="${basedir}/src/submods/metrics-lib/generated/javadoc"
                  prefix="metrics-lib" />
      <zipfileset dir="${libs}" prefix="WEB-INF/lib" >
        <include name="taglibs-standard-impl-1.2.5.jar"/>
      </zipfileset>

      <metainf dir="${resources}"
               includes="context.xml"/>
      <manifest>
        <attribute name="Implemented-By" value="The Tor Project" />
        <attribute name="Implementation-Title" value="TorMetricsWeb Server"/>
        <attribute name="Implementation-Version"
                   value="${release.version}-${git.revision}"/>
        <attribute name="Main-Class"
                   value="org.torproject.metrics.web.ServerMain" />
      </manifest>
    </war>
  </target>

  <target name="generate-ml-javadoc" depends="submoduleupdate" >
    <mkdir dir="${basedir}/src/submods/metrics-lib/lib" />
    <exec executable="ant"
          dir="${basedir}/src/submods/metrics-lib"
          failonerror="true" >
      <arg value="clean" />
      <arg value="resolve" />
      <arg value="docs" />
    </exec>
  </target>

  <target name="generate-graphviz-pngs" >
    <apply executable="dot"
           dest="${basedir}/src/main/resources/web/images"
           verbose="true" >
      <arg value="-Tpng" />
      <arg value="-o" />
      <targetfile />
      <srcfile />
      <fileset dir="${basedir}/src/main/resources/graphviz" >
        <include name="*.gv" />
      </fileset>
      <mapper type="glob" from="*.gv" to="*.png" />
    </apply>
  </target>

  <target name="generate-news-json" >
    <echo message="Running java module UpdateNews ... " />
    <available file="${dist}/${jarfile}" property="have.jar"/>
    <fail unless="have.jar" message="Please run 'ant jar' first."/>
    <java classname="org.torproject.metrics.web.UpdateNews">
      <arg value="${basedir}/src/main/resources/web/json/news.json" />
      <classpath>
        <pathelement location="${dist}/${jarfile}" />
        <pathelement location="${resources}" />
      </classpath>
    </java>
    <echo message="Java module UpdateNews finished. " />
  </target>

  <target name="generate-specs" depends="init" >
    <mkdir dir="${specdir}" />
    <antcall target="xml2jsp">
      <param name="specfile" value="bridge-descriptors"/>
    </antcall>
    <antcall target="xml2jsp">
      <param name="specfile" value="web-server-logs"/>
    </antcall>
  </target>

  <target name="xml2jsp" >
    <echo message="Generating ${specfile} specification jsp ... " />
    <exec executable="saxon-xslt"
          dir="${specdir}"
          logError="true"
          output="${specdir}/${specfile}.tmp"
          failonerror="true" >
      <arg value="${basedir}/${resources}/spec/${specfile}.xml" />
      <arg value="${basedir}/${resources}/spec/rfc2629.xslt" />
      <arg value="xml2rfc-topblock=no" />
    </exec>
    <exec executable="tidy"
          dir="${specdir}"
          logError="true"
          output="${specdir}/${specfile}.tmp2"
          failonerror="true" >
      <arg value="-quiet" />
      <arg value="${specdir}/${specfile}.tmp" />
    </exec>
    <exec executable="awk"
          dir="${specdir}"
          logError="true"
          output="${resources}/web/jsps/${specfile}.jsp"
          failonerror="true" >
      <arg value="-f" />
      <arg value="${basedir}/${resources}/spec/convert.awk" />
      <arg value="${specdir}/${specfile}.tmp2" />
    </exec>
    <echo message="Done." />
    <delete file="${specdir}/${specfile}.tmp" quiet="true" />
    <delete file="${specdir}/${specfile}.tmp2" quiet="true" />
  </target>

  <!--
      The run-rserver target documents a working option of
      configuring an R server for running metrics-web.
      It is not necessary for development to use this task
      and it is not used for metrics.torproject.org in this way.
      Eventually, this task will become obsolete when R is also
      controlled from Java code.
  -->
  <target name="run-rserver">
    <exec executable="R"
          dir="${Rsources}/rserver"
          failonerror="true" >
      <arg value="CMD"/>
      <arg value="Rserve" />
      <arg value="--no-save" />
      <arg value="--quiet" />
      <arg value="--RS-conf" />
      <arg value="${Rsources}/Rserv.conf" />
    </exec>
  </target>

  <target name="fetch-exonerator" depends="init"
          description="Fetch ExoneraTor from dist.torproject.org">
    <mkdir dir="${downloadedlibs}"/>
    <get src="https://dist.torproject.org/exonerator/${exoneratorversion}/exonerator-${exoneratorversion}.tar.gz"
         dest="${downloadedlibs}"/>
    <untar src="${downloadedlibs}/exonerator-${exoneratorversion}.tar.gz"
           dest="${libs}" compression="gzip">
      <patternset>
        <include name="**/exonerator-${exoneratorversion}-thin.jar"/>
      </patternset>
      <mapper type="flatten"/>
    </untar>
  </target>

  <target name="update-fallback-dir-list"
          description="Update the fallback directory list used by Relay Search">
    <exec executable="bash">
      <arg value="-c"/>
      <arg value="python3 src/main/python/fallback_dir.py | tee src/main/resources/web/js/rs/fallback_dir.js"/>
    </exec>
  </target>

  <!-- The following line adds the common targets and properties
       for Metrics' Java Projects.
  -->
  &base;

</project>

