<?xml version="1.0"?>

<project name="azkaban" basedir="." default="all"
    xmlns:ivy="antlib:org.apache.ivy.ant">
  <property file="build.properties" />
  <property name="base.dir" value="${basedir}" />
  <property name="dist.jar.dir" value="${basedir}/dist/jars" />
  <property name="dist.dust.dir" value="${basedir}/dist/dust" />
  <property name="dist.less.dir" value="${basedir}/dist/less" />
  <property name="dist.web.dir" value="${basedir}/dist/web" />
  <property name="dist.classes.dir" value="${basedir}/dist/classes" />
  <property name="dist.packages.dir" value="${basedir}/dist/packages" />
  <property name="dist.web.package.dir" value="${dist.packages.dir}/azkaban-web-server" />
  <property name="dist.exec.package.dir" value="${dist.packages.dir}/azkaban-exec-server" />
  <property name="dist.solo.package.dir" value="${dist.packages.dir}/azkaban-solo-server" />
  <property name="dist.sql.package.dir" value="${dist.packages.dir}/sql" />  

  <property name="conf.dir" value="${basedir}/conf" />
  <property name="web.package.dir" value="${basedir}/src/package/webserver" />
  <property name="exec.package.dir" value="${basedir}/src/package/execserver" />
  <property name="solo.package.dir" value="${basedir}/src/package/soloserver" />
  
  <property name="bin.dir" value="${basedir}/bin" />
  <property name="java.src.dir" value="${basedir}/src/java" />
  <property name="dust.src.dir" value="${basedir}/src/tl" />
  <property name="less.src.dir" value="${basedir}/src/less" />
  <property name="web.src.dir" value="${basedir}/src/web" />
  <property name="sql.src.dir" value="${basedir}/src/sql" />
  
  <property name="version.file" value="${dist.packages.dir}/azkaban.version" />
  
  <!-- Ivy properties -->
  <property name="mvnrepo" value="http://repo2.maven.org/maven2" />
  <property name="build.dir" value="${base.dir}/build" />
  <property name="ivy.dir" location="ivy" />
  <loadproperties srcfile="${ivy.dir}/libraries.properties" />
  
  <property name="loglevel" value="default" />
  <property name="ivy.jar" value="${ivy.dir}/ivy-${ivy.version}.jar" />
  <property name="ivy.repo.url" 
      value="${mvnrepo}/org/apache/ivy/ivy/${ivy.version}/ivy-${ivy.version}.jar" />
  <property name="ivysettings.xml" value="${ivy.dir}/ivysettings.xml" />
  <property name="build.ivy.dir" location="${build.dir}/ivy" />
  <property name="build.ivy.lib.dir" location="${build.ivy.dir}/lib" />
  <property name="ivy.artifact.retrieve.pattern" value="[artifact]-[revision].[ext]" />

  <property environment="env" />

  <path id="main.classpath">
    <fileset dir="${build.ivy.lib.dir}">
      <include name="*.jar" />
    </fileset>

    <pathelement path="${dist.classes.dir}" />
  </path>

  <!-- set the build number based on environment variable, otherwise blank -->
  <property environment="env" description="System environment variables (including those set by Hudson)" />
  
  <target name="all" depends="clean, package" description="Builds jars and packages." />
  
  <target name="ivy-probe-antlib">
    <condition property="ivy.found">
      <typefound uri="antlib:org.apache.ivy.ant" name="cleancache" />
    </condition>
  </target>

  <target name="ivy-download" description="Downloads Ivy." unless="offline">
    <get src="${ivy.repo.url}" dest="${ivy.jar}" usetimestamp="true" />
  </target>

  <target name="ivy-init-dirs">
    <mkdir dir="${build.ivy.dir}" />
    <mkdir dir="${build.ivy.lib.dir}" />
  </target>

  <target name="ivy-init-antlib" depends="ivy-download, ivy-init-dirs, ivy-probe-antlib" unless="ivy.found">
    <typedef uri="antlib:org.apache.ivy.ant" onerror="fail" loaderRef="ivyLoader">
      <classpath>
        <pathelement location="${ivy.jar}" />
      </classpath>
    </typedef>
    <fail>
      <condition>
        <not>
          <typefound uri="antlib:org.apache.ivy.ant" name="cleancache" />
        </not>
      </condition>
      You need Apache Ivy 2.0 or later from http://ant.apache.org/
      It sould not be loaded from ${ivy.repo.url}
    </fail>
  </target>

  <target name="ivy-init" depends="ivy-init-antlib">
    <ivy:configure settingsid="${ant.project.name}.ivy.settings" file="${ivysettings.xml}" override="false" />
  </target>

  <target name="ivy-resolve" depends="ivy-init" description="Resolve dependencies with Ivy">
    <ivy:resolve settingsRef="${ant.project.name}.ivy.settings" log="${loglevel}" />
  </target>

  <target name="ivy-retrieve" depends="ivy-resolve" description="Retrieve Ivy-managed artifacts.">
    <ivy:retrieve settingsRef="${ant.project.name}.ivy.settings"
        pattern="${build.ivy.lib.dir}/${ivy.artifact.retrieve.pattern}" log="${loglevel}" />
  </target>
  
  <available file=".git" type="dir" property="git.present"/>
  <target name="git.info" description="Store git info" if="git.present">
    <exec executable="git" outputproperty="git.commithash" failifexecutionfails="false" errorproperty="">
      <arg value="rev-parse"/>
      <arg value="HEAD"/>
    </exec>
  
    <exec executable="git" outputproperty="git.repo" failifexecutionfails="false" errorproperty="">
      <arg value="config"/>
      <arg value="--get"/>
      <arg value="remote.origin.url"/>
    </exec>
  
    <exec executable="git" outputproperty="git.tag" failifexecutionfails="false" errorproperty="">
      <arg value="describe"/>
      <arg value="--abbrev=0"/>
      <arg value="--tags"/>
    </exec>
    <condition property="git.tag" value="${git.tag}" else="${version}">
      <and>
        <isset property="git.tag"/>
        <length string="${git.tag}" trim="yes" length="0" when="greater"/>
      </and>
    </condition>
    <echo>Git tag found to be ${git.commithash} with tag ${git.tag} from repo ${git.repo}</echo>
  </target>
  
  <target name="clean" description="Delete generated files.">
    <echo message="Deleting generated files in dist" />
    <delete dir="${dist.jar.dir}" />
    <delete dir="${dist.classes.dir}" />
    <delete dir="${dist.dust.dir}" />
    <delete dir="${dist.less.dir}" />
    <exec dir="${dust.src.dir}" executable="make" failonerror="true">
      <arg value="clean" />
    </exec>
    <exec dir="${less.src.dir}" executable="make" failonerror="true">
      <arg value="clean" />
    </exec>
		<subant target="clean">
			<fileset dir="unit" includes="build.xml" />
		</subant>
  </target>
  
  <target name="distclean" depends="clean" description="Delete all generated files.">
    <delete dir="${build.dir}" />
    <delete>
      <fileset dir="${ivy.dir}">
        <include name="*.jar" />
      </fileset>
    </delete>
  </target>

  <target name="dust" description="Compile Less css files.">
    <!-- Compile dustjs templates -->
    <delete dir="${dist.dust.dir}" />
    <mkdir dir="${dist.dust.dir}" />
    <exec dir="${dust.src.dir}" executable="make" failonerror="true"/>
    <copy todir="${dist.dust.dir}">
      <fileset dir="${dust.src.dir}/obj" includes="*.js" />
    </copy>
  </target>
  
  <target name="less" description="Compile Less css files.">
    <!-- Compile LESS to CSS -->
    <delete dir="${dist.less.dir}" />
    <mkdir dir="${dist.less.dir}" />
    <exec dir="${less.src.dir}" executable="make" failonerror="true"/>
    <copy todir="${dist.less.dir}" >
      <fileset dir="${less.src.dir}/obj" includes="*.css" />
    </copy>
  </target>
  
  <target name="repo.file" depends="git.info" description="Create a file to reference the git commit">
    <delete file="azkaban.version" />
    
    <tstamp>
      <format timezone="UTC" property="current.time" pattern="yyyy-MM-dd hh:mm zzz"/>
    </tstamp>
    
    <!-- Need to remove indents of the echo contents, because echo into file includes the tabs -->
<echo file="${version.file}">
${git.tag}
${git.commithash}
${git.repo}
${current.time}
</echo>
  </target>
  
  <target name="build" depends="git.info, repo.file, ivy-retrieve" description="Compile main source tree java files">
    <echo>Building Classes</echo>
    <delete dir="${dist.classes.dir}" />
    <mkdir dir="${dist.classes.dir}" />
    
    <!-- copy non-java files to classes dir to load from classpath -->
    <copy todir="${dist.classes.dir}">
      <fileset dir="${java.src.dir}">
        <exclude name="**/*.java" />
      </fileset>
    </copy>
    
    <javac fork="true" destdir="${dist.classes.dir}"
      target="1.6" debug="true" deprecation="false" failonerror="true">
      <src path="${java.src.dir}" />
      <classpath refid="main.classpath" />
    </javac>

    <antcall target="dust"></antcall>
    <antcall target="less"></antcall>
  </target>
  
  <target name="webmin" description="Copies only the non compiled web resources to dist dir">
    <copy todir="${dist.web.dir}" overwrite="true">
      <fileset dir="${web.src.dir}" />
    </copy>
  </target>
  
  <target name="web" description="Creates web resourses in a dir. Useful for development">
    <mkdir dir="${dist.web.dir}" />
    
    <antcall target="webmin"></antcall>
    <antcall target="dust"></antcall>
    <antcall target="less"></antcall>
    
    <!-- Copy compiled dust templates -->
    <copy todir="${dist.web.dir}/js">
      <fileset dir="${dist.dust.dir}" />
    </copy>

    <!-- Copy compiled less CSS -->
    <copy todir="${dist.web.dir}/css">
      <fileset dir="${dist.less.dir}" />
    </copy>
  </target>
  
  <target name="jars" depends="build" description="Create azkaban jar">
    <mkdir dir="${dist.jar.dir}" />
    <jar destfile="${dist.jar.dir}/azkaban-${git.tag}.jar">
      <fileset dir="${dist.classes.dir}">
        <include name="**/*.*" />
      </fileset>
    </jar>
  </target>
  
  <target name="create-update-script" description="Prepare the creation of the Azkaban Scripts">
    <!-- Generic update table scripts -->
    <concat destfile="${dist.sql.package.dir}/update-all-sql-${updateVersion}.sql" fixlastline="yes">
      <fileset dir="${sql.src.dir}" >
        <include name="update.*.${updateVersion}.sql"/>
      </fileset>
    </concat>
  </target>
  
  <target name="create-update-script-2.1" description="Prepare the creation of the Azkaban Scripts">
    <!-- 2.1 added the active_sla table -->
    <concat destfile="${dist.sql.package.dir}/update-all-sql-2.1.sql" fixlastline="yes">
      <fileset dir="${sql.src.dir}" >
        <include name="create.active_sla.sql"/>
        <include name="update.*.2.1.sql"/>
      </fileset>
    </concat>
  </target>
  
  <target name="create-update-script-2.2" description="Prepare the creation of the Azkaban Scripts">
    <!-- 2.2 added the properties table -->
    <concat destfile="${dist.sql.package.dir}/update-all-sql-2.2.sql" fixlastline="yes">
      <fileset dir="${sql.src.dir}" >
        <include name="create.properties.sql"/>
        <include name="update.*.2.2.sql"/>
      </fileset>
    </concat>
  </target>
  
  <target name="package-sql-scripts" description="Creates a package of sql">
    <delete dir="${dist.sql.package.dir}" />
    <mkdir dir="${dist.sql.package.dir}" />

    <concat destfile="${dist.sql.package.dir}/create-all-sql-${git.tag}.sql" fixlastline="yes">
      <fileset dir="${sql.src.dir}" >
        <exclude name="update.*.sql"/>
        <exclude name="database.properties"/>
      </fileset>
    </concat>
    
    <!-- Collect various update scripts. -->
    <!-- Not sure how to do this better yet. -->
    <antcall target="create-update-script-2.1"></antcall>
    <antcall target="create-update-script-2.2"></antcall>
    <!-- End script collection-->
    
    <copy todir="${dist.sql.package.dir}" >
      <fileset dir="${sql.src.dir}" />
    </copy>
    <echo file="${dist.sql.package.dir}/database.properties" append="true">version=${git.tag}</echo>

    <tar destfile="${dist.sql.package.dir}/${name}-sql-script-${git.tag}.tar.gz" compression="gzip" longfile="gnu">
      <tarfileset dir="${dist.sql.package.dir}" prefix="azkaban-${git.tag}" filemode="755" />
    </tar>
  </target>

  <target name="package-web-server" depends="jars" description="Creates a package for the webserver">
    <delete dir="${dist.web.package.dir}" />
    <mkdir dir="${dist.web.package.dir}" />
    <mkdir dir="${dist.web.package.dir}/conf" />
    <mkdir dir="${dist.web.package.dir}/bin" />
    <mkdir dir="${dist.web.package.dir}/lib" />
    <mkdir dir="${dist.web.package.dir}/web" />
    <mkdir dir="${dist.web.package.dir}/plugins" />
    <mkdir dir="${dist.web.package.dir}/extlib" />
      
    <!-- Copy Azkaban jars and libs-->
    <copy file="${dist.jar.dir}/azkaban-${git.tag}.jar" todir="${dist.web.package.dir}/lib" />
    <copy todir="${dist.web.package.dir}/lib" >
      <fileset dir="${build.ivy.lib.dir}" >
        <exclude name="hadoop-core*.jar"/>
      </fileset>
    </copy>
    
    <!-- Copy bin files for web server only-->
    <copy todir="${dist.web.package.dir}/bin">
      <fileset dir="${web.package.dir}/bin"/>
    </copy>
    
    <!-- Copy web files -->
    <copy todir="${dist.web.package.dir}/web">
      <fileset dir="${web.src.dir}" />
    </copy>

    <!-- Copy compiled dust templates -->
    <copy todir="${dist.web.package.dir}/web/js">
      <fileset dir="${dist.dust.dir}" />
    </copy>

    <!-- Copy compiled less CSS -->
    <copy todir="${dist.web.package.dir}/web/css">
      <fileset dir="${dist.less.dir}" />
    </copy>
    
    <!-- Copy conf create table scripts -->
    <copy todir="${dist.web.package.dir}/conf">
      <fileset dir="${web.package.dir}/conf" />
    </copy>
    
    <!-- Copy version file -->
    <copy file="${version.file}" todir="${dist.web.package.dir}" />
    
    <!-- Tarball it -->
    <tar destfile="${dist.web.package.dir}/${name}-web-server-${git.tag}.tar.gz" compression="gzip" longfile="gnu">
      <tarfileset dir="${dist.web.package.dir}" prefix="azkaban-${git.tag}" filemode="755" includes="bin/*" />
      
      <tarfileset dir="${dist.web.package.dir}" prefix="azkaban-${git.tag}" includes="**">
        <exclude name="bin/*"/>
      </tarfileset>
    </tar>
  </target>
  
  <target name="package-exec-server" depends="jars" description="Creates a package for the execserver">
    <delete dir="${dist.exec.package.dir}" />
    <mkdir dir="${dist.exec.package.dir}" />
    <mkdir dir="${dist.exec.package.dir}/conf" />
    <mkdir dir="${dist.exec.package.dir}/bin" />
    <mkdir dir="${dist.exec.package.dir}/lib" />
    <mkdir dir="${dist.exec.package.dir}/plugins" />
    <mkdir dir="${dist.exec.package.dir}/extlib" />
        
    <!-- Copy Azkaban jars and libs-->
    <copy file="${dist.jar.dir}/azkaban-${git.tag}.jar" todir="${dist.exec.package.dir}/lib" />
    <copy todir="${dist.exec.package.dir}/lib" >
      <fileset dir="${build.ivy.lib.dir}" >
        <exclude name="hadoop-core*.jar"/>
      </fileset>
    </copy>
    
    <!-- Copy bin files for exec server only-->
    <copy todir="${dist.exec.package.dir}/bin" >
      <fileset dir="${exec.package.dir}/bin"/>
    </copy>

    <!-- Copy conf files -->
    <copy todir="${dist.exec.package.dir}/conf" >
      <fileset dir="${exec.package.dir}/conf" />
    </copy>
    
    <!-- Copy version file -->
    <copy file="${version.file}" todir="${dist.exec.package.dir}" />
    
    <!-- Tarball it -->
    <tar destfile="${dist.exec.package.dir}/${name}-executor-server-${git.tag}.tar.gz" compression="gzip" longfile="gnu">
      <tarfileset dir="${dist.exec.package.dir}" prefix="azkaban-${git.tag}" filemode="755" includes="bin/*" />
      
      <tarfileset dir="${dist.exec.package.dir}" prefix="azkaban-${git.tag}" includes="**">
        <exclude name="bin/*"/>
      </tarfileset>
    </tar>
  </target>
  
  <target name="package-solo-server" depends="jars" description="Creates a package for the solo server">
    <delete dir="${dist.solo.package.dir}" />
    <mkdir dir="${dist.solo.package.dir}" />
    <mkdir dir="${dist.solo.package.dir}/conf" />
    <mkdir dir="${dist.solo.package.dir}/bin" />
    <mkdir dir="${dist.solo.package.dir}/lib" />
    <mkdir dir="${dist.solo.package.dir}/plugins" />
    <mkdir dir="${dist.solo.package.dir}/extlib" />
    <mkdir dir="${dist.solo.package.dir}/sql" />
        
    <!-- Copy Azkaban jars and libs-->
    <copy file="${dist.jar.dir}/azkaban-${git.tag}.jar" todir="${dist.solo.package.dir}/lib" />
    <copy todir="${dist.solo.package.dir}/lib" >
      <fileset dir="${build.ivy.lib.dir}" >
        <exclude name="hadoop-core*.jar"/>
      </fileset>
    </copy>
    
    <!-- Copy bin files for exec server only-->
    <copy todir="${dist.solo.package.dir}/bin" >
      <fileset dir="${solo.package.dir}/bin"/>
    </copy>

    <!-- Copy conf files -->
    <copy todir="${dist.solo.package.dir}/conf" >
      <fileset dir="${solo.package.dir}/conf" />
    </copy>
    
    <!-- Copy web files -->
    <copy todir="${dist.solo.package.dir}/web" >
      <fileset dir="${web.src.dir}" />
    </copy>
    
    <!-- Copy compiled dust templates -->
    <copy todir="${dist.solo.package.dir}/web/js">
      <fileset dir="${dist.dust.dir}" />
    </copy>
    
    <!-- Copy compiled less CSS -->
    <copy todir="${dist.solo.package.dir}/web/css">
      <fileset dir="${dist.less.dir}" />
    </copy>
    
    <!-- Copy sql files -->
    <copy todir="${dist.solo.package.dir}/sql" >
      <fileset dir="${sql.src.dir}" />
    </copy>
    <echo file="${dist.solo.package.dir}/sql/database.properties" append="true">version=${git.tag}</echo>
    
    <!-- Copy version file -->
    <copy file="${version.file}" todir="${dist.solo.package.dir}" />

    <!-- Tarball it -->
    <tar destfile="${dist.solo.package.dir}/${name}-solo-server-${git.tag}.tar.gz" compression="gzip" longfile="gnu">
      <tarfileset dir="${dist.solo.package.dir}" prefix="azkaban-${git.tag}" filemode="755" includes="bin/*" />
      
      <tarfileset dir="${dist.solo.package.dir}" prefix="azkaban-${git.tag}" includes="**">
        <exclude name="bin/*"/>
      </tarfileset>
    </tar>
  </target>
  
  <target name="package-all" depends="package-exec-server, package-web-server, package-solo-server, package-sql-scripts" description="Create all packages">
  </target>

  <target name="package" depends="package-all" description="Create all packages">
  </target>

  <target name="test" depends="jars" description="Build and run tests">
		<subant target="all">
			<fileset dir="unit" includes="build.xml" />
		</subant>
  </target>

</project>
