/*
 * 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 --deselect apache_beam/yaml/integration_tests.py::BigqueryTest::test_ReadFromBigQuery_ExternalJavaProvider_0 --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"
    }
  }
}
