/*
 * Copyright 2011 gitblit.com.
 *
 * Licensed 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.
 */
import com.gitblit.GitBlit
import com.gitblit.Keys
import com.gitblit.models.RepositoryModel
import com.gitblit.models.UserModel
import com.gitblit.utils.JGitUtils
import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.revwalk.RevCommit
import org.eclipse.jgit.transport.ReceiveCommand
import org.eclipse.jgit.transport.ReceiveCommand.Result
import org.slf4j.Logger

/**
 * Sample Gitblit Post-Receive Hook: fisheye
 *
 * The Post-Receive hook is executed AFTER the pushed commits have been applied
 * to the Git repository.  This is the appropriate point to trigger an
 * integration build or to send a notification.
 * 
 * This script is only executed when pushing to *Gitblit*, not to other Git
 * tooling you may be using.
 * 
 * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
 * or web.xml then it will be executed by any repository when it receives a
 * push.  If you choose to share your script then you may have to consider
 * tailoring control-flow based on repository access restrictions.
 *
 * Scripts may also be specified per-repository in the repository settings page.
 * Shared scripts will be excluded from this list of available scripts.
 * 
 * This script is dynamically reloaded and it is executed within it's own
 * exception handler so it will not crash another script nor crash Gitblit.
 * 
 * Bound Variables:
 *  gitblit			Gitblit Server	 			com.gitblit.GitBlit
 *  repository		Gitblit Repository			com.gitblit.models.RepositoryModel
 *  receivePack		JGit Receive Pack			org.eclipse.jgit.transport.ReceivePack
 *  user			Gitblit User				com.gitblit.models.UserModel
 *  commands		JGit commands 				Collection<org.eclipse.jgit.transport.ReceiveCommand>
 *	url				Base url for Gitblit		String
 *  logger			Logs messages to Gitblit 	org.slf4j.Logger
 *  clientLogger	Logs messages to Git client	com.gitblit.utils.ClientLogger
 *
 * Accessing Gitblit Custom Fields:
 *   def myCustomField = repository.customFields.myCustomField
 *  
 */
// Indicate we have started the script
logger.info("fisheye hook triggered by ${user.username} for ${repository.name}")

// define your fisheye url here or set groovy.fisheyeServer in 
// gitblit.properties or web.xml
def fisheyeUrl = gitblit.getString('groovy.fisheyeServer', 'http://yourserver/jenkins')

// define your fisheye API token or set groovy.fisheyeApiToken in
// gitblit.properties or web.xml
def fisheyeApiToken = gitblit.getString('groovy.fisheyeApiToken', '')

// whether to remove .git suffix from repository name
// may be defined in gitblit.properties or web.xml
def fisheyeRemoveGitSuffix = gitblit.getBoolean('groovy.fisheyeRemoveGitSuffix', false)

def repoName = repository.name
if (fisheyeRemoveGitSuffix && repoName.toLowerCase().endsWith('.git')) repoName = repoName.substring(0, repoName.length() - 4)

// define the trigger url
def triggerUrl = "$fisheyeUrl/rest-service-fecru/admin/repositories-v1/$repoName/scan"

// trigger the build
def _url = new URL(triggerUrl)
def _con = _url.openConnection()

// set up connection
_con.setRequestMethod("POST")
_con.setRequestProperty("X-Api-Key", fisheyeApiToken)
_con.setRequestProperty("User-Agent", "Gitblit")

// send post request
_con.setDoOutput(true)

logger.info("fisheye response code: ${_con.responseCode}")
