#!/usr/bin/env python
#
# Copyright (c) 2014, 2015, 2016 Samsung Electronics.Co.Ltd.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; version 2 of the License
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
"""This job is triggered by gerrit submit ref update event for preloaded app.
   It will generate tizen app package(.tpk) and requests prerelease routine.
"""

import os
import sys
import ast
from pprint import pprint

sys.path.insert(1, os.path.join(sys.path[0], '..'))

from common.git import Git, clone_gitproject
from common.mapping import git_obs_map, git_obs_map_full_list
from common.gerrit import is_ref_deleted
from common.buildtrigger import trigger_info, trigger_next

# set default char-set endcoding to utf-8
reload(sys)
sys.setdefaultencoding('utf-8') # pylint: disable-msg=E1101


def list_all_packages(profile):

    list_all = []

    if True:
        mapping_list = git_obs_map_full_list(obs_project=profile, staging_project='abs')
        for item in mapping_list:
            if not all(name in ['Project_name', 'Branch_name', \
                    'OBS_project', 'OBS_staging_project', 'OBS_package'] for name in item):
                continue
            prj_name = item['Project_name']
            _branch = item['Branch_name']
            _obs_prj = item['OBS_project']
            _stg = item['OBS_staging_project']
            _pkg = item['OBS_package']
            _brch = ''
            for _br in _branch.split(','):
                if _brch == '' or len(_br) < len(_brch):
                    _brch = _br
            print '  >> Adding %s(%s) %s %s' % (prj_name, _brch, _obs_prj, _pkg)
            list_all.append(item)
    return list_all

def find_build_list():
    # Make required paremeters as dictionary
    events = []
    if os.getenv('BUILD_CAUSE') is None:
        event = {}
        event['BUILD_CAUSE']   = os.getenv('BUILD_CAUSE')
        event['PROJECT']       = None
        event['GIT_PATH']      = os.getenv('GERRIT_PROJECT')
        event['TAG_NAME']      = os.getenv('GERRIT_REFNAME').replace('refs/tags/', '')
        event['BRANCH']        = event.get('TAG_NAME')[len('submit/'):event.get('TAG_NAME').rfind('/', len('submit/'))]
        event['REVISION']      = os.getenv('GERRIT_NEWREV')
        event['USER_EMAIL']    = os.getenv('GERRIT_EVENT_ACCOUNT_EMAIL')
        # Find project mappings
        obs_target_prjs = git_obs_map(event.get('GIT_PATH'), \
                                      event.get('BRANCH'))
        for item in obs_target_prjs:
            if item.get('OBS_staging_project') != 'abs':
                continue
            event['PROJECT'] = item.get('OBS_project')
            event['PACKAGE_NAME_FROM_MAPPING'] = item.get('OBS_package')
            events.append(event)
    elif os.getenv('BUILD_CAUSE') is not None:
        mainProject = os.getenv('BUILD_CAUSE').split(',')[0]
        obs_target_prjs = list_all_packages(mainProject)
        for item in obs_target_prjs:
            if item.get('OBS_staging_project') != 'abs':
                continue
            event = {}
            event['BUILD_CAUSE']   = os.getenv('BUILD_CAUSE')
            event['PROJECT']       = mainProject
            event['GIT_PATH']      = item.get('Project_name')
            event['TAG_NAME']      = None
            event['BRANCH']        = item.get('Branch_name')
            event['REVISION']      = None
            event['USER_EMAIL']    = None
            events.append(event)

    return events

def parseConf(mainProject, index):

    confData = {}

    # Get script path from system config file
    meta_script_map = ast.literal_eval(os.getenv('ABS_CLI_SCRIPT_GIT_MAP'))
    meta_script = meta_script_map.get('default')
    if meta_script_map.get(mainProject) is not None:
        meta_script = meta_script_map.get(mainProject)
    print 'meta_script:%s' % meta_script

    # Fetch project environment variables from config git
    configPath = os.path.join(os.getenv('WORKSPACE'), 'abs_config_%d' % index)
    if not clone_gitproject(meta_script.split(',')[0], \
                            configPath, \
                            git_cache_dir='non-exist-dir'):
        print 'Wrapper script %s clone fail' % meta_script.split(',')[0]
        sys.exit(3)
    workingGit = Git(configPath)
    workingGit.checkout(meta_script.split(',')[1])

    # Save project environment variables
    if not os.path.isfile(os.path.join(configPath, 'conf.%s' % mainProject)):
        print 'No conf.%s' % mainProject
        return None
    with open(os.path.join(configPath, 'conf.%s' % mainProject), 'r') as rf:
        confContents = rf.readlines()
        print "%s" % confContents
    for x in confContents:
        confData[x.split('=')[0]] = x.split('=')[1].strip()

    confData['ABS_CLI_SCRIPT_GIT'] = meta_script

    return confData

def main(argv):
    """
    Script entry point.
    """

    # Regular Gerrit Event
    # Required fields checking
    for ev in ['GERRIT_REFNAME', 'GERRIT_PROJECT', 'GERRIT_NEWREV', 'GERRIT_EVENT_ACCOUNT_EMAIL']:
        if ev not in os.environ and os.getenv('BUILD_CAUSE') is None:
            print 'Required event parameters are missing %s' % ev
            sys.exit(4)

    if is_ref_deleted(os.getenv('GERRIT_OLDREV'), os.getenv('GERRIT_NEWREV')):
        print 'REF DELETED(%s)!' % os.getenv('GERRIT_OLDREV')
        return

    fullList = find_build_list()
    pprint(fullList)

    index = 1
    confData = None
    for events in fullList:

        extra_params = {'BACKEND_SELECTION': 'ABS', 'ABS_WORKSPACE': '/home/build/workspace'}
        extra_params.update(events)

        if events.get('BUILD_CAUSE') is None:
            confData = parseConf(events.get('PROJECT'), index)
        elif confData is None:
            confData = parseConf(events.get('PROJECT'), index)
        if confData is None:
            continue
        extra_params.update(confData)

        for key, value in extra_params.items():
            if value is None:
                extra_params[key] = ''
        pprint(extra_params)

        # Forward it to build job
        trigger_next('ABS_BUILD_%d_%d_%s' \
                     % (int(os.getenv('BUILD_NUMBER')), index, os.path.basename(events.get('GIT_PATH'))), \
                     {'ABS_SERVER_TYPE': 'DOCKER'}, extra_params=extra_params)
        index += 1

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

