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

// Define common lifecycle tasks and artifact types
apply plugin: "base"

// Publish website to asf-git branch.
apply plugin: 'org.ajoberstar.grgit'

def dockerImageTag = 'beam-website'
def dockerWorkDir = "/repo"
def buildDir = "${project.rootDir}/build/website"
def buildContentDir = "${project.rootDir}/build/website/generated-content"
def repoContentDir = "${project.rootDir}/website/generated-content"
def commitedChanges = false
def gitboxUrl = project.findProperty('gitPublishRemote') ?: 'https://gitbox.apache.org/repos/asf/beam.git'

def shell = { cmd ->
  println cmd
  exec {
    executable 'sh'
    args '-c', cmd
  } 
}


def envdir = "${buildDir}/gradleenv"

task setupVirtualenv {
  doLast {
    exec {
      commandLine 'virtualenv', "${envdir}"
    }
    exec {
      executable 'sh'
      args '-c', ". ${envdir}/bin/activate && pip install beautifulsoup4"
    }
  }
  outputs.dirs(envdir)
}

task buildDockerImage(type: Exec) {
  inputs.files 'Gemfile', 'Gemfile.lock'
  commandLine 'docker', 'build', '-t', dockerImageTag, '.'
}

task createDockerContainer(type: Exec) {
  dependsOn buildDockerImage
  standardOutput = new ByteArrayOutputStream()
  ext.containerId = {
    return standardOutput.toString().trim()
  }
  def extraOptions = ''
  if (project.hasProperty('publishJekyllPort')) {
    extraOptions = '-p 127.0.0.1:4000:4000'
  }
  commandLine '/bin/bash', '-c',
    "docker create -v $project.rootDir:$dockerWorkDir -u \$(id -u):\$(id -g) $extraOptions $dockerImageTag"
}

task startDockerContainer(type: Exec) {
  dependsOn createDockerContainer
  ext.containerId = {
    return createDockerContainer.containerId()
  }
  commandLine 'docker', 'start',
    "${->createDockerContainer.containerId()}" // Lazily evaluate containerId.
}

task stopAndRemoveDockerContainer(type: Exec) {
  commandLine 'docker', 'rm', '-f', "${->createDockerContainer.containerId()}"
}

task setupBuildDir(type: Copy) {
  from('.') {
    include 'Gemfile*'
    include 'Rakefile'
  }
  into buildDir
}

task cleanWebsite(type: Delete) {
  delete buildDir
}
clean.dependsOn cleanWebsite

task buildWebsite(type: Exec) {
  def baseurlFlag = project.findProperty('githubPullRequestId') ? "--baseurl=/${project.findProperty('githubPullRequestId')}" : ''
  dependsOn startDockerContainer, setupBuildDir
  finalizedBy stopAndRemoveDockerContainer
  inputs.files 'Gemfile.lock', '_config.yml'
  inputs.dir 'src'
  inputs.property 'baseurl', baseurlFlag
  outputs.dir "$buildDir/.sass-cache"
  outputs.dir buildContentDir
  commandLine 'docker', 'exec',
    "${->startDockerContainer.containerId()}", '/bin/bash', '-c',
    """cd $dockerWorkDir/build/website && \
      bundle exec jekyll build \
      --config $dockerWorkDir/website/_config.yml \
      --incremental ${baseurlFlag} \
      --source $dockerWorkDir/website/src
      """
}
build.dependsOn buildWebsite

task serveWebsite(type: Exec) {
  dependsOn startDockerContainer, setupBuildDir
  finalizedBy stopAndRemoveDockerContainer
  inputs.files 'Gemfile.lock', '_config.yml'
  inputs.dir 'src'
  outputs.dir "$buildDir/.sass-cache"
  outputs.dir buildContentDir
  commandLine 'docker', 'exec',
    "${->startDockerContainer.containerId()}", '/bin/bash', '-c',
    """cd $dockerWorkDir/build/website && \
      bundle exec jekyll serve \
      --config $dockerWorkDir/website/_config.yml \
      --incremental \
      --source $dockerWorkDir/website/src \
      --host 0.0.0.0
      """
}

task testWebsite(type: Exec) {
  dependsOn startDockerContainer, buildWebsite
  finalizedBy stopAndRemoveDockerContainer

  inputs.files "$buildDir/Rakefile"
  inputs.dir buildContentDir
  commandLine 'docker', 'exec',
    "${->startDockerContainer.containerId()}", '/bin/bash', '-c',
    """cd $dockerWorkDir/build/website && \
      bundle exec rake test"""
}

check.dependsOn testWebsite

task preCommit {
  dependsOn testWebsite
}

// Creates a new commit on asf-site branch
task commitWebsite << {
  assert file("${buildContentDir}/index.html").exists()
  // Generated javadoc and pydoc content is not built or stored in this repo.
  assert !file("${buildContentDir}/documentation/sdks/javadoc").exists()
  assert !file("${buildContentDir}/documentation/sdks/pydoc").exists()

  def git = grgit.open()
  // get the latest commit on master
  def latestCommit = grgit.log(maxCommits: 1)[0].abbreviatedId

  shell "git fetch --force origin +asf-site:asf-site"
  git.checkout(branch: 'asf-site')

  // Delete the previous content.
  git.remove(patterns: [ 'website/generated-content' ])
  assert !file("${repoContentDir}/index.html").exists()
  delete repoContentDir

  // Copy the built content and add it.
  copy {
    from buildContentDir
    into repoContentDir
  }
  assert file("${repoContentDir}/index.html").exists()
  git.add(patterns: ['website/generated-content'])

  def currentDate = new Date().format('yyyy/MM/dd HH:mm:ss')
  String message = "Publishing website ${currentDate} at commit ${latestCommit}"
  if (git.status().isClean()) {
    println 'No changes to commit'
  } else {
    println 'Creating commit for changes'
    commitedChanges = true
    git.commit(message: message)
  }
}

/*
 * Pushes the asf-site branch commits.
 *
 * This requires write access to the asf-site branch and can be run on
 * Jenkins executors with the git-websites label.
 *
 * For more details on publishing, see:
 * https://www.apache.org/dev/project-site.html
 * https://github.com/apache/infrastructure-puppet/blob/deployment/modules/gitwcsub/files/config/gitwcsub.cfg
 *
 * You can test this locally with a forked repository by manually adding the
 * website-publish remote pointing to your forked repository, for example:
 *   git remote add website-publish git@github.com:${GITUSER}/beam.git
 * because the remote is only added if it doesn't exist. The remote needs
 * to be added before every execution of the publishing.
 */
task publishWebsite << {
  def git = grgit.open()
  git.checkout(branch: 'asf-site')
  if (!commitedChanges) {
    println 'No changes to push'
    return
  }

  // Because git.push() fails to authenticate, run git push directly.
  shell "git push ${gitboxUrl} asf-site"
}

commitWebsite.dependsOn buildWebsite
publishWebsite.dependsOn commitWebsite

/*
 * Stages a pull request on GCS
 * For example:
 *   ./gradlew :beam-website:stageWebsite -PgithubPullRequestId=${ghprbPullId} -PwebsiteBucket=foo
 */
task stageWebsite << {
  assert project.hasProperty('githubPullRequestId')
  assert githubPullRequestId.isInteger()

  def gcs_bucket = project.findProperty('websiteBucket') ?: 'apache-beam-website-pull-requests'
  def gcs_path = "gs://${gcs_bucket}/${githubPullRequestId}"

  // Remove current site if it exists.
  shell "gsutil -m rm -r -f ${gcs_path} || true"

  // Fixup the links to index.html files
  shell "cd ${buildDir} && ln -s generated-content content || true"
  shell ". ${envdir}/bin/activate && cd ${buildDir} && " +
        "python ${project.rootDir}/website/.jenkins/append_index_html_to_internal_links.py"

  // Copy the build website to GCS
  shell "gsutil -m cp -r ${buildContentDir} ${gcs_path}"

  println "Website published to http://${gcs_bucket}." +
      "storage.googleapis.com/${githubPullRequestId}/index.html"
}

stageWebsite.dependsOn setupVirtualenv
stageWebsite.dependsOn buildWebsite
