/*
 * 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
 *
 *     http://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.
 */

plugins { id 'org.apache.beam.module' }
applyPythonNature()


/*************************************************************************************************/
// Basic build and Python environment setup/cleanup

def buildPython = tasks.register("buildPython") {
  dependsOn setupVirtualenv

  doLast {
    logger.info('Building Python Dependencies')
    exec {
      executable 'sh'
      // args '-c', ". ${envdir}/bin/activate && python setup.py build --build-base ${buildDir}"
      args '-c', ". ${envdir}/bin/activate && pip install -e ."
    }
  }
}
build.dependsOn tasks.named("buildPython")

// Create a Python source distribution tarball.
def tarball = "apache-beam.tar.gz"
def sdist = tasks.register("sdist") {
  description "Create a Python source distribution tarball"
  dependsOn setupVirtualenv

  doLast {
    // Build artifact
    exec {
      executable 'sh'
      args '-c', ". ${envdir}/bin/activate && pip install -U build && python -m build --sdist --outdir=${buildDir}"
    }

    def collection = fileTree(buildDir){ include "**/*${project.sdk_version}*.tar.gz" exclude 'srcs/**'}

    // we need a fixed name for the artifact
    copy { from collection.singleFile; into buildDir; rename { tarball } }
    logger.info('Create distribution tar file {} in {}', tarball, buildDir)
  }
  inputs.files(pythonSdkDeps)
      .withPropertyName('pythonSdkDeps')
      .withPathSensitivity(PathSensitivity.RELATIVE)
  outputs.file "${buildDir}/${tarball}"
}

artifacts {
  distTarBall file: file("${buildDir}/${tarball}"), builtBy: sdist
}

tasks.register("generateExternalTransformsConfig") {
  description "Discovers external transforms and regenerates the config at sdks/standard_expansion_services.yaml"

  dependsOn buildPython
  // Need to build all expansion services listed in sdks/standard_expansion_services.yaml
  dependsOn ":sdks:java:io:google-cloud-platform:expansion-service:build"
  dependsOn ":sdks:java:io:expansion-service:build"
  dependsOn ":sdks:java:io:messaging-expansion-service:build"
  // Keep this in-sync with pyproject.toml
  def PyYaml = "'pyyaml>=3.12,<7.0.0'"

  doLast {
    exec {
      executable 'sh'
      args '-c', "pip install $PyYaml && " +
              "python gen_xlang_wrappers.py --cleanup --generate-config-only"
    }
  }
}

tasks.register("generateManagedIOPage") {
  description "Generages the Managed Connectors Beam page based on SchemaTransform metadata"

  dependsOn buildPython
  // Need to build all expansion services listed in apache_beam/transforms/managed.py
  dependsOn ":sdks:java:io:google-cloud-platform:expansion-service:build"
  dependsOn ":sdks:java:io:expansion-service:build"

  doLast {
    exec {
      executable 'sh'
      args '-c', "python gen_managed_doc.py"
    }
  }
}

tasks.register("prepareExpansionServicesForYamlDocs") {
  description "Builds all expansion services referenced in apache_beam/yaml/*.*"

  dependsOn ":sdks:java:extensions:schemaio-expansion-service:shadowJar"
  dependsOn ":sdks:java:extensions:sql:expansion-service:shadowJar"
  dependsOn ":sdks:java:io:expansion-service:shadowJar"
  dependsOn ":sdks:java:io:google-cloud-platform:expansion-service:shadowJar"

  doLast {
    // Copy expansion service jar into cache path (.apache_beam/cache/jars/).
    copy {
      from project.tasks.findByPath(":sdks:java:extensions:schemaio-expansion-service:shadowJar")
      from project.tasks.findByPath(":sdks:java:extensions:sql:expansion-service:shadowJar")
      from project.tasks.findByPath(":sdks:java:io:expansion-service:shadowJar")
      from project.tasks.findByPath(":sdks:java:io:google-cloud-platform:expansion-service:shadowJar")
      into "${System.getProperty('user.home')}/.apache_beam/cache/jars/"
    }
  }
}

tasks.register("generateYamlDocs") {
  description "Generates the reference documentation for all YAML transforms."

  dependsOn buildPython
  dependsOn prepareExpansionServicesForYamlDocs

  def extraPackages = "pyyaml markdown docstring_parser pandas pygments Jinja2 virtualenv-clone"

  doLast {
    exec {
      executable 'sh'
      args '-c', "${envdir}/bin/pip install $extraPackages && " +
              "${envdir}/bin/python -m apache_beam.yaml.generate_yaml_docs --html_file=${buildDir}/yaml-ref.html --examples_file=${buildDir}/yaml-examples.html"
    }
  }
  outputs.file "${buildDir}/yaml-ref.html"
  outputs.file "${buildDir}/yaml-examples.html"
}

tasks.register("yamlIntegrationTests") {
  description "Runs precommit integration tests for yaml pipelines."

  dependsOn installGcpTest
  // Need to build all expansion services referenced in apache_beam/yaml/*.*
  // grep -oh 'sdk.*Jar' sdks/python/apache_beam/yaml/*.yaml | sort | uniq
  dependsOn ":sdks:java:extensions:schemaio-expansion-service:shadowJar"
  dependsOn ":sdks:java:extensions:sql:expansion-service:shadowJar"
  dependsOn ":sdks:java:io:expansion-service:build"
  dependsOn ":sdks:java:io:google-cloud-platform:expansion-service:build"
  dependsOn ":sdks:java:io:debezium:expansion-service:shadowJar"

  doLast {
    exec {
      executable 'sh'
      args '-c', "${envdir}/bin/pytest -v apache_beam/yaml/integration_tests.py"
    }
  }
}

tasks.register("postCommitYamlIntegrationTests") {
  description "Runs postcommit integration tests for yaml pipelines - parameterized by yamlTestSet."

  dependsOn installGcpTest
  // Need to build all expansion services referenced in apache_beam/yaml/*.*
  // grep -oh 'sdk.*Jar' sdks/python/apache_beam/yaml/*.yaml | sort | uniq
  dependsOn ":sdks:java:extensions:schemaio-expansion-service:shadowJar"
  dependsOn ":sdks:java:extensions:sql:expansion-service:shadowJar"
  dependsOn ":sdks:java:io:expansion-service:build"
  dependsOn ":sdks:java:io:google-cloud-platform:expansion-service:build"
  dependsOn ":sdks:java:io:debezium:expansion-service:shadowJar"

  doLast {
    def testSetInput = project.findProperty('yamlTestSet') ?: 'data,databases,messaging'
    def testSetsToRun = testSetInput.tokenize(',').collect { it.trim() }.findAll { !it.isEmpty() }
    testSetsToRun.each { currentTestSet ->
      def test_files_dir

      switch (currentTestSet) {
        case 'data':
          test_files_dir = 'extended_tests/data'
          break
        case 'databases':
          test_files_dir = 'extended_tests/databases'
          break
        case 'messaging':
          test_files_dir = 'extended_tests/messaging'
          break
        default:
          throw StopExecutionException("Unknown yamlTestSet: ${currentTestSet}. Must be one of 'data', 'databases', or 'messaging'.")
      }
      exec {
        executable 'sh'
        args '-c', "${envdir}/bin/pytest -v apache_beam/yaml/integration_tests.py --test_files_dir='${test_files_dir}'"
      }
    }
  }
}

// Create Python wheels for given platform and Python version
// build identifiers for cibuildwheel
def platform_identifiers_map = [
  linux: 'manylinux_*64*', // e.g. manylinux_x86_64, manylinux_aarch64
  macos:'macosx_*64*',     // e.g. macosx_x86_64, macosx_arm64
  windows: 'win_*64*',     // e.g. win_amd64, win_arm64
]

platform_identifiers_map.each { platform, idsuffix ->
  def archs = 'auto'
  // note: A fix for arm64 platform in gradle environment. For some reason the
  // task fails with "Invalid archs option {<Architecture.arm64: 'arm64'>}."
  // even though os.arch is 'aarch64'
  // Running cibuildwheel command directly in shell it succeeded, however
  if (platform == 'linux' && 'aarch64'.equalsIgnoreCase(System.getProperty("os.arch"))) {
    archs = 'aarch64'
  }
  getVersionsAsList('python_versions').each { it ->
    def pyversion = it.replace('.', '')
    def cibuildwheel_version = it == '3.10' ? '2.23.3' : '3.4.0'

    project.tasks.register("bdistPy${pyversion}${platform}") {
      description "Build a Python wheel distribution for Py${pyversion} ${platform}"
      dependsOn setupVirtualenv
      // need sdist task to generate protos
      dependsOn ':sdks:python:sdist'

      // generated installable Python SDK package
      doLast {
        int maxRetries = 3
        int retryCount = 0
        // note(https://github.com/pypa/cibuildwheel/issues/1692): cibuildwheel appears to timeout occasionally.
        while (retryCount < maxRetries) {
          try {
            exec {
             environment CIBW_BUILD: "cp${pyversion}-${idsuffix}"
             executable 'sh'
             args '-c', ". ${envdir}/bin/activate && " +
                 // note: sync cibuildwheel version with GitHub Action
                 // .github/workflows/build_wheel.yml:build_wheels "Install cibuildwheel" step
                 "pip install cibuildwheel==${cibuildwheel_version} setuptools && " +
                 "cibuildwheel --print-build-identifiers --platform ${platform} --archs ${archs} && " +
                 "cibuildwheel --output-dir ${buildDir} --platform ${platform} --archs ${archs} "
           }
           break;
         }
         catch (Exception e) {
            retryCount++
            if (retryCount < maxRetries) {
                println "cibuildwheel failed on attempt ${retryCount}. Will retry."
            } else {
                throw e
            }
         }
        }
      }
    }
  }
}


/*************************************************************************************************/
// Non-testing builds and analysis tasks

// Snapshot of dependency requirements defined in setup.py.
// Results will be stored in files under Gradle build directory.
def depSnapshot = tasks.register("depSnapshot") {
  dependsOn installGcpTest

  doLast {
    def outputDir = file(buildDir)
    if (!outputDir.exists()) {
      outputDir.mkdirs()
    }
    def requirementsFile = "${outputDir}/requirements.txt"

    logger.info('Snapshoting full dependencies requirements with versions info to build/requirements.txt.')
    exec {
      // Remove useless item "pkg-resources" from file which is introduced by a bug in Ubuntu.
      executable 'sh'
      args '-c', ". ${envdir}/bin/activate && pip freeze --local --all | grep -v \"pkg-resources\" > ${requirementsFile}"
    }
  }
}

tasks.register("buildSnapshot") {
  dependsOn sdist
  dependsOn depSnapshot
}

tasks.register("startPortableRunner") {
  dependsOn buildPython

  doLast {
    def jobPort = project.findProperty("jobPort") ?: 8099
    exec {
      executable 'sh'
      args '-c', ". ${envdir}/bin/activate && python -m apache_beam.runners.portability.local_job_service_main --job_port ${jobPort}"
    }
  }
}

// Run this task to validate the python environment setup for contributors
tasks.register("wordCount") {
  description "Run the Python word count example"
  dependsOn installGcpTest
  doLast {
    exec {
      executable 'sh'
      args '-c', ". ${envdir}/bin/activate && python -m apache_beam.examples.wordcount --runner DirectRunner --output /tmp/output.txt"
    }
  }
}
