/*
 * 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('.', '')

    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==2.23.3 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"
    }
  }
}
