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

<!--
   Copyright (c) 2009, 2025 Mountainminds GmbH & Co. KG and Contributors
   This program and the accompanying materials are made available under
   the terms of the Eclipse Public License 2.0 which is available at
   http://www.eclipse.org/legal/epl-2.0

   SPDX-License-Identifier: EPL-2.0

   Contributors:
      Marc R. Hoffmann - initial API and implementation
-->

<project name="JaCoCo Instrument Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant">

	<target name="setUp">
		<tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" />
		<mkdir dir="${temp.dir}"/>
		<property name="exec.file" location="${temp.dir}/exec.file" />
	</target>

	<target name="tearDown">
		<delete dir="${temp.dir}" quiet="false" failonerror="true"/>
	</target>

	<target name="testInstrumentNoDestination">
		<au:expectfailure expectedMessage="Destination directory must be supplied">
			<jacoco:instrument/>
		</au:expectfailure>
	</target>

	<target name="testInstrumentInvalidClassFile">
		<mkdir dir="${temp.dir}/output"/>
		<property name="broken.file" location="${temp.dir}/broken.class"/>
		<copy file="${org.jacoco.ant.instrumentTaskTest.classes.dir}/TestTargetInDefault.class" tofile="${broken.file}"/>
		<truncate file="${broken.file}" length="8"/>
		<au:expectfailure expectedMessage="Error while instrumenting ${broken.file}">
			<jacoco:instrument destdir="${temp.dir}/output">
				<fileset dir="${temp.dir}" includes="broken.class"/>
			</jacoco:instrument>
		</au:expectfailure>
		<au:assertFileDoesntExist file="${temp.dir}/output/broken.class" />
	</target>

	<target name="testInstrumentIgnoreDirectories">
		<jacoco:instrument destdir="${temp.dir}">
			<dirset dir="${org.jacoco.ant.instrumentTaskTest.classes.dir}" includes="**"/>
		</jacoco:instrument>
	</target>

	<target name="testInstrumentRemoveSignatures">
		<property name="lib.dir" location="${temp.dir}/lib"/>
		<property name="instr.dir" location="${temp.dir}/instr"/>
		<mkdir dir="${lib.dir}"/>
		<mkdir dir="${instr.dir}"/>

		<jar destfile="${lib.dir}/test.jar">
			<fileset dir="${org.jacoco.ant.instrumentTaskTest.classes.dir}" includes="**/*.class"/>
		</jar>
		<signjar jar="${lib.dir}/test.jar" keystore="${basedir}/data/keystore.jks" alias="test" storepass="password"/>

		<jacoco:instrument destdir="${instr.dir}">
			<fileset dir="${lib.dir}" includes="*.jar"/>
		</jacoco:instrument>
		<au:assertLogContains text="Instrumented 17 classes to ${temp.dir}"/>

		<unzip src="${instr.dir}/test.jar" dest="${instr.dir}"/>
		<au:assertFileDoesntExist file="${instr.dir}/META-INF/TEST.RSA" />
		<au:assertFileDoesntExist file="${instr.dir}/META-INF/TEST.SF" />
	</target>

	<target name="testInstrumentKeepSignatures">
		<property name="lib.dir" location="${temp.dir}/lib"/>
		<property name="instr.dir" location="${temp.dir}/instr"/>
		<mkdir dir="${lib.dir}"/>
		<mkdir dir="${instr.dir}"/>

		<jar destfile="${lib.dir}/test.jar">
			<fileset dir="${org.jacoco.ant.instrumentTaskTest.classes.dir}" includes="**/*.class"/>
		</jar>
		<signjar jar="${lib.dir}/test.jar" keystore="${basedir}/data/keystore.jks" alias="test" storepass="password"/>

		<jacoco:instrument destdir="${instr.dir}" removesignatures="false">
			<fileset dir="${lib.dir}" includes="*.jar"/>
		</jacoco:instrument>
		<au:assertLogContains text="Instrumented 17 classes to ${temp.dir}"/>

		<unzip src="${instr.dir}/test.jar" dest="${instr.dir}"/>
		<au:assertFileExists file="${instr.dir}/META-INF/TEST.RSA" />
		<au:assertFileExists file="${instr.dir}/META-INF/TEST.SF" />
	</target>

	<target name="testInstrumentAndRunWithConfigFile">
		<jacoco:instrument destdir="${temp.dir}">
			<fileset dir="${org.jacoco.ant.instrumentTaskTest.classes.dir}" includes="**/*.class"/>
		</jacoco:instrument>
		<au:assertLogContains text="Instrumented 17 classes to ${temp.dir}"/>
		<au:assertFileExists file="${temp.dir}/org/jacoco/ant/InstrumentTaskTest.class" />

		<echo file="${temp.dir}/jacoco-agent.properties">destfile=test.exec</echo>
		<java classname="org.jacoco.ant.TestTarget" failonerror="true" fork="true" dir="${temp.dir}">
			<classpath>
				<pathelement path="${org.jacoco.ant.instrumentTaskTest.agent.file}"/>
				<pathelement path="${temp.dir}"/>
			</classpath>
		</java>
		<au:assertFileExists file="${temp.dir}/test.exec" />
	</target>

	<target name="testInstrumentAndRunWithSystemProperties">
		<jacoco:instrument destdir="${temp.dir}">
			<fileset dir="${org.jacoco.ant.instrumentTaskTest.classes.dir}" includes="**/*.class"/>
		</jacoco:instrument>
		<au:assertLogContains text="Instrumented 17 classes to ${temp.dir}"/>
		<au:assertFileExists file="${temp.dir}/org/jacoco/ant/InstrumentTaskTest.class" />

		<java classname="org.jacoco.ant.TestTarget" failonerror="true" fork="true">
			<sysproperty key="jacoco-agent.destfile" file="${temp.dir}/test.exec"/>
			<classpath>
				<pathelement path="${org.jacoco.ant.instrumentTaskTest.agent.file}"/>
				<pathelement path="${temp.dir}"/>
			</classpath>
		</java>
		<au:assertFileExists file="${temp.dir}/test.exec" />
	</target>

	<target name="testInstrumentWithRuntimeStartupFailure">
		<jacoco:instrument destdir="${temp.dir}">
			<fileset dir="${org.jacoco.ant.instrumentTaskTest.classes.dir}" includes="**/*.class"/>
		</jacoco:instrument>
		<au:assertLogContains text="Instrumented 17 classes to ${temp.dir}"/>
		<au:assertFileExists file="${temp.dir}/org/jacoco/ant/InstrumentTaskTest.class" />

		<java classname="org.jacoco.ant.TestTarget" failonerror="false" fork="true">
			<sysproperty key="jacoco-agent.output" value="tcpserver"/>
			<sysproperty key="jacoco-agent.port" value="foo"/>
			<classpath>
				<pathelement path="${org.jacoco.ant.instrumentTaskTest.agent.file}"/>
				<pathelement path="${temp.dir}"/>
			</classpath>
		</java>
		<au:assertLogContains text="java.lang.RuntimeException: Failed to initialize JaCoCo."/>
		<au:assertLogContains text="java.lang.NumberFormatException: For input string: &quot;foo&quot;"/>
	</target>

</project>
