<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->
<project default="compile" name="s3"
         xmlns:ivy="antlib:org.apache.ivy.ant"
         xmlns:if="ant:if">

  <!-- easy way to override properties -->
  <property file="build.properties"/>

  <!-- don't fork junit; regexp classes not available -->
  <property name="junit.fork" value="false" />

  <property name="javac.-source" value="1.8" />
  <property name="javac.-target" value="1.8" />

  <import file="common/build.xml"/>

  <target name="install-all" depends="install">
    <ivy:retrieve pattern="${ant.home}/lib/[artifact]-[revision].[ext]" conf="default" />
  </target>

  <target name="ready-to-test-with-antunit" depends="common.ready-to-test-with-antunit,antunit-prepare" />

  <target name="antunit-prepare" depends="setup-s3">
<!--
  	<path id="antlib.cp">
      <path refid="classpath.test" />
      <pathelement location="${target.jar}" />
  	</path>
    <classloader classpathref="antlib.cp" />
  	<typedef resource="org/apache/ant/s3/antlib.xml" uri="antlib:org/apache/ant/s3" classpathref="antlib.cp" />
  	<typedef resource="org/apache/ant/s3cs/antlib.xml" uri="antlib:org/apache/ant/s3cs" classpathref="antlib.cp" />
-->
  	<path id="classpath.antlib">
      <path refid="classpath.test" />
      <pathelement location="${target.jar}" />
  	</path>
  </target>

  <target name="groovy-setup" depends="resolve">
    <presetdef name="groovy">
      <script manager="javax" classpathref="classpath.test" language="groovy" />
    </presetdef>
  </target>

  <target name="start-s3" depends="groovy-setup">
    <property name="s3.start" value="true" />
    <groovy if:true="${s3.start}">
      def s3Mock = com.adobe.testing.s3mock.S3MockApplication.start('--initialBuckets=foo,bar')
      project.addReference('s3Mock', s3Mock)
    </groovy>
  </target>

  <target name="setup-s3" depends="start-s3">
    <property name="s3.setup" value="true" />
    <groovy>
      import static com.adobe.testing.s3mock.S3MockApplication.DEFAULT_HTTPS_PORT
      import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES

      import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
      import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
      import software.amazon.awssdk.core.sync.RequestBody
      import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient
      import software.amazon.awssdk.regions.Region
      import software.amazon.awssdk.services.s3.S3Client
      import software.amazon.awssdk.utils.AttributeMap

      def s3Endpoint = "https://localhost:${DEFAULT_HTTPS_PORT}"
      project.setProperty('s3.endpoint', s3Endpoint)

      def s3 = { -> S3Client.builder()
        .region(Region.of("us-east-1"))
        .credentialsProvider(
          StaticCredentialsProvider.create(
            AwsBasicCredentials.create("foo", "bar")
          )
        )
        .endpointOverride(URI.create(s3Endpoint))
        .httpClient(
          UrlConnectionHttpClient.builder().buildWithDefaults(
            AttributeMap.builder().put(TRUST_ALL_CERTIFICATES, Boolean.TRUE).build()
          )
        )
        .build()
      }

      project.addReference("s3g", s3)

      if (Boolean.parseBoolean(project.getProperty('s3.setup'))) {
        s3 = s3()

        try (s3) {
          ['a', 'b', 'c'].each {
            s3.putObject({ b -> b.bucket('foo').key(it).metadata([B: 'foo']).tagging("T1=${it}") }, RequestBody.fromString(it))
          }
          ['x', 'y', 'z'].each {
            s3.putObject({ b -> b.bucket('bar').key(it).metadata([B: 'bar']).tagging("T1=${it}") }, RequestBody.fromString(it))
          }
        }
      }
    </groovy>
    <echo>$${s3.endpoint}=${s3.endpoint}</echo>
  </target>

  <target name="antunit-test" depends="ready-to-test-with-antunit,resolve"
  	    unless="skip-antunit">
    <condition property="antunit.includes" value="${antunit.testcase}"
               else="**/test.xml,**/*-test.xml">
      <isset property="antunit.testcase" />
    </condition>

    <property name="antunit.excludes" value="" />

    <mkdir dir="${antunit.report.dir}" />

  	<au:antunit xmlns:au="antlib:org.apache.ant.antunit"
      failOnError="false"
      errorProperty="antunit.tests.failed"
      >
      <fileset dir="${src.antunit}" includes="${antunit.includes}"
               excludes="${antunit.excludes}" />

      <au:xmllistener todir="${antunit.report.dir}" />
      <au:plainlistener/>
      <propertyset>
        <propertyref name="s3.endpoint" />
      </propertyset>
      <au:reference refid="ant.coreLoader" />
      <au:reference refid="classpath.antlib" />
    </au:antunit>

    <groovy if:true="${s3.start}">
      project.getReference('s3Mock').stop()
    </groovy>
  </target>

  <target name="stop-s3" depends="setup-s3">
    <groovy>
      project.getReference('s3Mock').stop()
    </groovy>
  </target>

  <target name="s3-test" depends="setup-s3">
    <groovy>
      try (def s3 = project.getReference('s3g')()) {
        println "BUCKETS: ${s3.listBuckets().buckets()}"
        println "FOO: ${s3.listObjectsV2 { b -> b.bucket('foo') }.contents()}"
        println "BAR: ${s3.listObjectsV2 { b -> b.bucket('bar') }.contents()}"
    	println "HEAD: ${s3.headObject { b -> b.bucket('foo').key('a') }}"
    	println "TAG: ${s3.getObjectTagging { b -> b.bucket('foo').key('a') }.tagSet()}"
      }
    </groovy>
  	<sequential if:true="${s3.start}">
      <input message="continue" />
      <groovy>
        project.getReference('s3Mock').stop()
      </groovy>
    </sequential>
  </target>

  <target name="groovy-test" depends="groovy-setup">
  	<groovy>
      println com.adobe.testing.s3mock.S3MockApplication.DEFAULT_HTTPS_PORT
  	</groovy>
  </target>
</project>
