#!/usr/bin/env python

import sys
import os
import atexit
import subprocess
import re
import glob
import datetime

from common.gbsutils import GBSBuild,gbs_remote_jenkins_build_job, gbs_update_dashboard
from common.buildtrigger import trigger_next,trigger_info

basic_url= os.getenv('URL_PUBLIC_REPO_BASE') + '/snapshots/tizen/'

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


def _check_mount_existance(build_root):
    print '----start _check_mount_existance-----------------------------------'
    umount_list = ''

    cmd='mount'
    result=subprocess.check_output(cmd,shell=True)
    for line in result.split('\n'):
        if line.find(build_root.replace('//','/')) != -1:
            umount_list+=line.split('on ')[1].split(' type')[0]+' '

    if umount_list:
        print 'There exist mount which is not unmouted by previous gbs fullbuild job.\n and these lists are like below:%s' %umount_list
        cmd='sudo umount '+umount_list
        subprocess.call(cmd, stdout=sys.stdout,stderr=sys.stderr, shell=True)
    else:
        print 'No mount is left by gbsfullbuild'

def trigger_bm_for_gbs_build_package(gbsbuild_tag,bm_pkg_info,bm_repo,bm_arch):
    print '----start get_bm_data_for_packages-----------------------------------'

    bm_pkg_git_repo_list = []
    bm_pkg_git_commit_id_list = []
    bm_pkg_spec_name_list = []
    bm_pkg_rpm_name_list = []
    bm_pkg_build_time_list = []
    bm_pkg_status_list = []
    bm_pkg_status_reason_list = []
    bm_trg_count = 0
    bm_pkg_count = 0
    BM_PKG_LIMIT = 500

    for bm_pkg in bm_pkg_info:
        bm_pkg_git_repo_list.append(bm_pkg['git_repository'])
        bm_pkg_git_commit_id_list.append(bm_pkg['git_commit_id'])
        bm_pkg_spec_name_list.append(bm_pkg['spec_file_name'])
        bm_pkg_rpm_name_list.append(bm_pkg['rpm_file_name'])
        bm_pkg_build_time_list.append(bm_pkg['build_time'])
        bm_pkg_status_list.append(bm_pkg['status'])
        bm_pkg_status_reason_list.append(bm_pkg['status_reason'])
        # divide the big pkgs
        bm_pkg_count += 1
        if bm_pkg_count >= BM_PKG_LIMIT:
            # for trigger
            bm_stage = 'GBSDBBuild_Package'
            bm_data = {"bm_stage" : bm_stage,
                       "gbsbuild_tag" : gbsbuild_tag,
                       "bm_repo" : bm_repo,
                       "bm_arch" : bm_arch,
                       "bm_pkg_git_repo_list" : bm_pkg_git_repo_list,
                       "bm_pkg_git_commit_id_list" : bm_pkg_git_commit_id_list,
                       "bm_pkg_spec_name_list" : bm_pkg_spec_name_list,
                       "bm_pkg_rpm_name_list" : bm_pkg_rpm_name_list,
                       "bm_pkg_build_time_list" : bm_pkg_build_time_list,
                       "bm_pkg_status_list" : bm_pkg_status_list,
                       "bm_pkg_status_reason_list" : bm_pkg_status_reason_list,
                       "bm_trg_count" : bm_trg_count,
                       "bm_pkg_count" : bm_pkg_count,
                       "BM_PKG_LIMIT" : BM_PKG_LIMIT,
                      }
            trigger_next("BUILD-MONITOR-2-%s-%s-%s-trg_%s" % (bm_stage, bm_repo, bm_arch, bm_trg_count), bm_data)
            # clear the data
            bm_pkg_count = 0
            bm_trg_count += 1
            bm_pkg_git_repo_list = []
            bm_pkg_git_commit_id_list = []
            bm_pkg_spec_name_list = []
            bm_pkg_rpm_name_list = []
            bm_pkg_build_time_list = []
            bm_pkg_status_list = []
            bm_pkg_status_reason_list = []

        # for rest pkgs
        bm_stage = 'GBSDBBuild_Package'
        bm_data = {"bm_stage" : bm_stage,
                   "gbsbuild_tag" : gbsbuild_tag,
                   "bm_repo" : bm_repo,
                   "bm_arch" : bm_arch,
                   "bm_pkg_git_repo_list" : bm_pkg_git_repo_list,
                   "bm_pkg_git_commit_id_list" : bm_pkg_git_commit_id_list,
                   "bm_pkg_spec_name_list" : bm_pkg_spec_name_list,
                   "bm_pkg_rpm_name_list" : bm_pkg_rpm_name_list,
                   "bm_pkg_build_time_list" : bm_pkg_build_time_list,
                   "bm_pkg_status_list" : bm_pkg_status_list,
                   "bm_pkg_status_reason_list" : bm_pkg_status_reason_list,
                   "bm_trg_count" : bm_trg_count,
                   "bm_pkg_count" : bm_pkg_count,
                   "BM_PKG_LIMIT" : BM_PKG_LIMIT,
                  }
        trigger_next("BUILD-MONITOR-2-%s-%s-%s-trg_%s" % (bm_stage, bm_repo, bm_arch, bm_trg_count), bm_data)


def update_db_for_gbsbuild_target(repository,architecture,bm_start_datetime,\
                                  gbs_build_status,gbsbuild_tag, status_reason=None):
    gbs_update_data = {"tag" : gbsbuild_tag,
                       "mode" : "build_finished",
                       "reason" : {"repo":repository,"arch":architecture,"status":gbs_build_status, "comment":status_reason}}
    gbs_update_dashboard(gbs_update_data,via='direct_call')

    bm_end_datetime = datetime.datetime.now()
    bm_stage = 'GBSDBBuild_Target'
    bm_data = {"bm_stage": bm_stage,
               "repository": repository,
               "architecture": architecture,
               "bm_start_datetime": str(bm_start_datetime),
               "bm_end_datetime" : str(bm_end_datetime),
               "gbs_build_status" : gbs_build_status,
               "gbsbuild_tag" : gbsbuild_tag
              }
    trigger_next("BUILD-MONITOR-1-%s" % bm_stage, bm_data)


def main():
    """script entry point"""

    print '---[JOB STARTED]----------------------------------------'

    content = trigger_info(os.getenv("TRIGGER_INFO"))
    gbsbuild_dic = content['gbsbuild_dic']
    repository = content['repository']
    architecture = content['architecture']
    new_pkg_list = content['new_pkg_list']
    rm_pkg_list = content['rm_pkg_list']
    rm_from_img_list = content['rm_from_img_list']

    global buildmonitor_enabled
    buildmonitor_enabled = os.getenv("BUILDMONITOR_ENABLED", "0") != "0"
    print 'buildmonitor_enabled(%s)\n' % (buildmonitor_enabled)

    # Update dashboard gbs build status
    if buildmonitor_enabled:
        gbs_update_data = {"tag" : gbsbuild_dic['gbsbuild_tag'],
                           "mode" : "build_started",
                           "reason" : {"repo":repository,"arch":architecture}}
        gbs_update_dashboard(gbs_update_data,via='direct_call')

    original_dir=os.getcwd()

    # clear files in /var/tmp/* where redundant files can be undeleted in case of abnormal gbs build break
    cmd = 'sudo rm -rf /vat/tmp/*'
    subprocess.call(cmd, stdout=sys.stdout,stderr=sys.stderr, shell=True)

    _check_mount_existance(gbsbuild_dic['build_root'])

    if os.path.exists(gbsbuild_dic['build_root']):
        cmd = 'sudo rm -rf '+gbsbuild_dic['build_root']
        subprocess.call(cmd, stdout=sys.stdout,stderr=sys.stderr, shell=True)

    if not os.path.exists(gbsbuild_dic['gbsbuild_workspace']):
        os.mkdir(gbsbuild_dic['gbsbuild_workspace'])

    if not os.path.exists(gbsbuild_dic['gbsbuild_workspace']+'/SRC-ROOT'):
        os.mkdir(gbsbuild_dic['gbsbuild_workspace']+'/SRC-ROOT')


    print 'gbs fullbuild start which links to obs project: %s' %gbsbuild_dic['obs_prj']

    bm_start_datetime = datetime.datetime.now()
    
    gbsbuild_sub = GBSBuild(gbsbuild_dic['gbsbuild_tag'], gbsbuild_dic['obs_prj'], basic_url,\
        gbsbuild_dic['snapshot_num'], gbsbuild_dic['trigger_category'], new_pkg_list, rm_pkg_list,\
        rm_from_img_list, gbsbuild_dic['add_to_img_list'], gbsbuild_dic['gbsbuild_workspace'])
    gbsbuild_sub_dic = gbsbuild_sub.convert_gbsbuild_to_dictionary()
    print "gbsbuild_sub_dic : %s" %gbsbuild_sub_dic

    print 'OBS Project: %s, repository: %s, architecture: %s gbs build start'\
        %(gbsbuild_dic['obs_prj'],repository,architecture)
    (repo_init_sync_status,repo_init_sync_status_reason) = gbsbuild_sub._do_repo_init_sync(repository)
    print repo_init_sync_status
    print repo_init_sync_status_reason
#tempary_test_code
#    return 0
    # if repo init or repo sync failed, do not perform gbs build, and just update dashboard
    if repo_init_sync_status == 'F':
        if buildmonitor_enabled:
            update_db_for_gbsbuild_target(repository,architecture,bm_start_datetime,\
                                          repo_init_sync_status,gbsbuild_dic['gbsbuild_tag'], status_reason=repo_init_sync_status_reason)
        return 0 

    (gbs_build_status,gbs_build_status_reason) = gbsbuild_sub._do_repo_arch_gbs_fullbuild(repository,architecture)

    live_out_dir=gbsbuild_sub.copy_build_results_to_dl_server(repository)

    os.chdir(original_dir)

    if buildmonitor_enabled:
        update_db_for_gbsbuild_target(repository,architecture,bm_start_datetime,\
                                      gbs_build_status,gbsbuild_dic['gbsbuild_tag'], status_reason = gbs_build_status_reason)

        bm_pkg_info=gbsbuild_sub.get_rpm_info_from_gbs_build_log(live_out_dir,repository,architecture)
        print "bm_pkg_info: %s" %bm_pkg_info
        trigger_bm_for_gbs_build_package(gbsbuild_dic['gbsbuild_tag'],bm_pkg_info,repository,architecture)


if __name__ == '__main__':
    sys.exit(main())

