#!/usr/bin/env python

import os
import sys
import json
import base64
import re
import time
import xml.etree.cElementTree as ElementTree
from xml.sax.saxutils import escape
from time import sleep

from osc import core
from gitbuildsys.errors import ObsError

from common import runner
from common import utils
from common.mapping import git_obs_map
from common.git import Git, clone_gitproject
from common.upload_service import upload_obs_service, UploadError
from common.gerrit import is_ref_deleted
from common.buildservice import BuildService
from common.buildtrigger import trigger_info, trigger_next
from common.backenddb import BackendDB
from common.prerelease import get_prerelease_project_name, prerelease_enabled
from common.iris_rest_client import IrisRestClient
from common.send_mail import prepare_mail
from common.gerrit import Gerrit, get_gerrit_event, GerritError, is_ref_deleted

from gbp.rpm import SpecFile
from gbp.git.repository import GitRepositoryError
from gbp.errors import GbpError


sr_tag=""
orig_git_user_name = ""
orig_git_user_email = ""

class LocalError(Exception):
    """Local error exception."""
    pass

def revert_git_config():

    # revert masqueraded user name/ email
    if orig_git_user_name != "":
        gitcmd = "git config user.name \"%s\"" % orig_git_user_name
        if runner.show(gitcmd)[0] != 0:
            raise Exception("failed to execute %s" % gitcmd)

    if orig_git_user_email != "":
        gitcmd = "git config user.email \"%s\"" % orig_git_user_email
        if runner.show(gitcmd)[0] != 0:
            raise Exception("failed to execute %s" % gitcmd)

def main():
    print '---[JOB STARTED]-------------------------'

    obs_api = os.getenv("OBS_API_URL")
    obs_user = os.getenv("OBS_API_USERNAME")
    obs_passwd = os.getenv("OBS_API_PASSWD")
    gerrit_project = os.getenv("GERRIT_PROJECT")
    gerrit_refname = os.getenv("GERRIT_REFNAME")
    gerrit_oldrev = os.getenv("GERRIT_OLDREV")
    gerrit_newrev = os.getenv("GERRIT_NEWREV")
    gerrit_account_name = os.getenv("GERRIT_EVENT_ACCOUNT_NAME")
    gerrit_account_email = os.getenv("GERRIT_EVENT_ACCOUNT_EMAIL")
  
    event = get_gerrit_event()

    # Init backend database
    redis_host = os.getenv("REDIS_HOST")
    redis_port = int(os.getenv("REDIS_PORT"))
    backenddb = BackendDB(redis_host, redis_port)

    global orig_git_user_name, orig_git_user_email

    # backup previous user.name and user.email
    gitcmd = "git config user.name"
    rcode, out = runner.show(gitcmd)
    if rcode != 0:
        print "failed to execute %s" % gitcmd
        return 1
    orig_git_user_name = out.strip()

    gitcmd = "git config user.email"
    rcode, out = runner.show(gitcmd)
    if rcode != 0:
        print "failed to execute %s" % gitcmd
        return 1
    orig_git_user_email = out.strip()

    os.environ["GIT_AUTHOR_EMAIL"] = event['tagger_useremail']
    os.environ["GIT_AUTHOR_NAME"] = event['tagger_username']

    git_cache = os.getenv("GIT_CACHE_DIR")
      
    # get a tag name (same as 'gbs submit')
    cur_timestamp = time.strftime('%Y%m%d.%H%M%S', time.gmtime())
    tag_name = "submit/%s/%s" % (event['branch'], cur_timestamp)

    projects = event['project'].split(',')
    commit_ids = event['commit_id'].split(',')
    for proj, commit in zip(projects, commit_ids):

      # prepare separate temp directory for each build
      prjdir = os.path.join(os.getenv('WORKSPACE'), proj)

      print "Cloning project %s..." % proj
      # clone gerrit project to local dir
      if not clone_gitproject(proj, prjdir):
          raise LocalError('Error cloning %s' % proj)

      mygit = Git(prjdir)

      # masquerade user name/ email
      cur_dir = os.getcwd()
      os.chdir(prjdir)
      gitcmd = "git config user.name \"%s\"" % (event['tagger_username'])
      if runner.show(gitcmd)[0] != 0:
          raise Exception("failed to execute %s" % gitcmd)
      gitcmd = "git config user.email \"%s\"" % (event['tagger_useremail'])
      if runner.show(gitcmd)[0] != 0:
          raise Exception("failed to execute %s" % gitcmd)
      os.chdir(cur_dir)

      branches = mygit.branch_contains(commit)
      if event['branch'] not in branches:
        raise LocalError("commit %s is not in branch %s" % (commit, event['branch']))

      print "Now creating tag for %s" %proj
      mygit.set_branch(event['branch'])
      mygit.checkout(commit)
      if 'sr_tag' in event:
        tag_name = event['sr_tag']
      global sr_tag
      sr_tag = tag_name
      try:
          mygit.create_tag(tag_name, event['tagger_submit_message'])
      except Exception as err:
          raise LocalError('Tag already exist %s' % proj)

    for proj, commit in zip(projects, commit_ids):
      print "Now creating tag for %s" %proj
      prjdir = os.path.join(os.getenv('WORKSPACE'), proj)
      mygit = Git(prjdir)
      mygit.set_branch(event['branch'])
      mygit.checkout(commit)
      mygit.push_tag("origin", tag_name)

    return 0

if __name__ == '__main__':
    exit_status = 0
    error_string = ""
    try:
        exit_status = main()
    except Exception as err:
        print err
        error_string = repr(err)
        exit_status = 1

    # status is changed to 'Succeeded' or 'Failed'
    status_str = "Processing"
    if exit_status != 0 :
        status_str = "Failed"

    sr_submit_log_id=(int)(os.getenv("GERRIT_SR_SUBMIT_LOG_ID"))
    bm_stage = "Add_Tag"

    bm_data = {"bm_stage": bm_stage,
               "sr_submit_log_id": sr_submit_log_id,
               "sr_tag": sr_tag,
               "status": status_str,
               "status_reason": error_string}
    trigger_next("BUILD-MONITOR", bm_data)

    sys.exit(exit_status)

