/*
 * 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"
  // 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("generateYamlDocs") {
  description "Generates the reference documentation for all YAML transforms."

  dependsOn buildPython
  // 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"
  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"

  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"

  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: ${testSet}. 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"
    }
  }
}
