#!/usr/bin/
#
# Copyright (c) 2018 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.
#
"""Buildmonitor extention"""

import os
import sys
import base64
import json
import copy
from datetime import datetime
from urllib import quote_plus
from common.buildtrigger import trigger_next, remote_jenkins_build_job

from buildmonitor_db import connect_db, disconnect_db, do_query, do_many_query, \
                            get_multi_values_from_query_data, get_value_from_query_data

class BuildMonitorExtention(object):
    """ Interface to BuildMonitor(Database) """
    def __init__(self):
        if os.getenv("BUILDMONITOR_ENABLED", "0") != "0":
            self.enabled = True
            #connect
            self.conn = connect_db()
            self.connect = True
        else:
           self.enabled = False
           self.conn = None
           self.connect = False
        print 'BuildMonitorExtention init'

    def __enter__(self):
        print 'BuildMonitorExtention enter'
        return self
 
    def __exit__(self, exc_type, exc_value, traceback):
        #disconnect
        if self.conn:
            disconnect_db()
            self.connect = False
        print 'BuildMonitorExtention exit'

    def is_connect(self):
        return self.connect

    def get_user_email_id(self, email):

        if not self.is_connect():
            return

        query = "SELECT id FROM user_email WHERE email = %s"
        query_data = (email,)

        return get_value_from_query_data(query, query_data)

    def update_user_email(self, email):

        if not self.is_connect():
            return

        query = "INSERT INTO user_email (email) SELECT * FROM (SELECT %s) AS tmp \
                 WHERE NOT EXISTS (SELECT email FROM user_email WHERE email = %s) LIMIT 1"
        do_query(query, (email, email))

    def get_auto_reject_projects(self):
        # get project in database
        # return : list

        if not self.is_connect():
            return []

        prj_list = {}

        query = "SELECT name, sr_auto_reject FROM main_project WHERE sr_auto_reject <> %s"
        query_data =("0",)

        projects = get_multi_values_from_query_data(query, query_data)
        if len(projects) and projects[0] == 0:
            return prj_list
        for prj in projects:
            prj_list[prj[0]] = int(prj[1]) #pylint: disable=unsubscriptable-object

        return prj_list

    def get_build_project_id(self, project):

        if not self.is_connect():
            return

        # get post_build_project_id
        # get last_bpid_of_build_snapshot
        query = "SELECT bp.id \
                 FROM build_project bp, info_project ip, build_snapshot bs \
                 WHERE ip.project_name = %s \
                 AND ip.id = bp.info_project_id \
                 AND bp.id = bs.build_project_id \
                 ORDER BY id desc LIMIT 1"
        query_data = (project,)
        build_project_id = get_value_from_query_data(query, query_data)
        print "build_project_id(%s)" % (build_project_id)

        return build_project_id

    def get_build_project_id_for_buildsnapshot(self, snapshot_name):

        if not self.is_connect():
            return

        print snapshot_name
        # get post_build_project_id
        query = "SELECT build_project_id \
                 FROM build_snapshot \
                 WHERE snapshot_name = %s \
                 ORDER BY id LIMIT 1"
        query_data = (snapshot_name, ) 
        build_project_id = get_value_from_query_data(query, query_data)
        print "1)build_project_id(%s)" % (build_project_id)
        return build_project_id

    def get_git_branch_id(self, branch):

        if not self.is_connect():
            return

        query = "SELECT id FROM git_branch WHERE name = %s"
        query_data = (branch,)

        return get_value_from_query_data(query, query_data)

    def update_git_branch(self, branch):

        if not self.is_connect():
            return

        query = "INSERT INTO git_branch (name) SELECT * FROM (SELECT %s) AS tmp \
                 WHERE NOT EXISTS (SELECT name FROM git_branch WHERE name = %s) LIMIT 1"
        do_query(query, (branch, branch))

    def get_repository_id(self, repo_name):

        if not self.is_connect():
            return

        # Select id from git_repository
        query = "SELECT id FROM git_repository WHERE name = %s"
        query_data = (repo_name,)

        return get_value_from_query_data(query, query_data)

    def update_repository(self, repo_name):

        if not self.is_connect():
            return

        query = "INSERT INTO git_repository (name) SELECT * FROM (SELECT %s) AS tmp \
                 WHERE NOT EXISTS (SELECT name FROM git_repository WHERE name = %s) LIMIT 1"
        do_query(query, (repo_name, repo_name))

    def get_commit_id(self, git_path_id, commit_id, branch_id=None):

        if not self.is_connect():
            return

        # Select id from git_commit
        if branch_id is None:
            query = "SELECT id FROM git_commit WHERE git_repository_id = %s AND commit_id = %s"
            query_data = (git_path_id, commit_id)
        else:
            query = "SELECT id FROM git_commit WHERE git_repository_id = %s AND commit_id = %s AND branch_id = %s"
            query_data = (git_path_id, commit_id, branch_id)

        return get_value_from_query_data(query, query_data)

    def update_commit(self, git_path_id, commit_id, commit_date, committer=None, commit_message=None):

        if not self.is_connect():
            return
       
        if committer and commit_message:
            query = "INSERT INTO git_commit (git_repository_id, commit_id, committer, commit_date, commit_message) \
                     SELECT * FROM (SELECT %s, %s, %s, %s, %s) AS tmp \
                     WHERE NOT EXISTS (SELECT git_repository_id, commit_id \
                     FROM git_commit WHERE git_repository_id = %s AND commit_id = %s) \
                     LIMIT 1"
            do_query(query, ('%d' % git_path_id, commit_id, committer, commit_date, commit_message, \
                             '%d' % git_path_id, commit_id))
        else:
            query = "INSERT INTO git_commit (git_repository_id, commit_id, commit_date) \
                     SELECT * FROM (SELECT %s, %s, %s) AS tmp \
                     WHERE NOT EXISTS (SELECT git_repository_id, commit_id \
                     FROM git_commit WHERE git_repository_id = %s AND commit_id = %s) \
                     LIMIT 1"
            do_query(query, ('%d' % git_path_id, commit_id, commit_date, \
                             '%d' % git_path_id, commit_id))

    def update_git_commit_strict(self, \
                             git_path=None, \
                             commit_id=None, \
                             committer=None, \
                             commit_date=None, \
                             commit_message=None, \
                             branch=None):

        if not self.is_connect():
            return

        if git_path is None or commit_id is None or committer is None \
            or commit_date is None or commit_message is None:
            return

        self.update_repository(git_path)
        db_git_path_id = self.get_repository_id(git_path)

        self.update_user_email(committer)
        db_user_email_id = self.get_user_email_id(committer)

        if branch is None or branch is '':
            branch = ''
        self.update_git_branch(branch)
        db_git_branch_id = self.get_git_branch_id(branch)

        if db_git_path_id == 0 or db_user_email_id == 0 or db_git_branch_id == 0:
            return

        db_git_commit_id = self.get_commit_id(db_git_path_id, commit_id, db_git_branch_id)

        if db_git_commit_id == 0:
            query = "INSERT INTO git_commit \
                     (git_repository_id, commit_id, commit_date, commit_message, \
                     committer_id, branch_id) \
                     VALUES(%s, %s, %s, %s, %s, %s)"
            query_data = (db_git_path_id, commit_id, commit_date, commit_message, \
                          db_user_email_id, db_git_branch_id)
            do_query(query, query_data)
            db_git_commit_id = self.get_commit_id(db_git_path_id, commit_id)
        else:
            query = "UPDATE git_commit SET \
                     git_repository_id=%s, commit_id=%s, commit_date=%s, commit_message=%s, \
                     committer_id=%s, branch_id=%s \
                     WHERE (id=%s) \
                     AND (commit_date <> %s OR commit_message <> %s \
                     OR committer_id <> %s OR branch_id <> %s)\
                     LIMIT 1"
            query_data = (db_git_path_id, commit_id, commit_date, commit_message, \
                          db_user_email_id, db_git_branch_id, db_git_commit_id,
                          commit_date, commit_message, db_user_email_id, db_git_branch_id)
            do_query(query, query_data)
            db_git_commit_id = self.get_commit_id(db_git_path_id, commit_id)

        return db_git_commit_id

    def get_tag_id(self, git_commit_id, tag_name, tag_revision):

        if not self.is_connect():
            return

        query = 'SELECT id FROM git_tag WHERE git_commit_id=%s AND tag_name=%s AND tag_revision=%s'
        return get_value_from_query_data(query, (git_commit_id, tag_name, tag_revision))

    def update_tag(self, git_commit_id, tag_name, tag_revision, tagger, tag_date, tag_message):

        if not self.is_connect():
            return

        query = "INSERT INTO git_tag (git_commit_id, tag_name, tag_revision, tagger, tag_date, tag_message) \
                 SELECT * FROM (SELECT %s, %s, %s, %s, %s, %s) AS tmp \
                 WHERE NOT EXISTS (SELECT git_commit_id, tag_revision \
                 FROM git_tag WHERE git_commit_id = %s AND tag_revision = %s) LIMIT 1"
        do_query(query, ('%d' % git_commit_id, tag_name, tag_revision, tagger, tag_date, tag_message, \
                         '%d' % git_commit_id, tag_revision))

    def delete_git_tag(self, git_path, tag_name, tag_rev, deleted_by, deleted_at):

        self.update_user_email(deleted_by)
        db_user_email_id = self.get_user_email_id(deleted_by)

        query = "SELECT gt.id FROM git_tag gt, git_commit gc, git_repository gr \
                 WHERE gr.name=%s AND gr.id=gc.git_repository_id AND gc.id=gt.git_commit_id \
                 AND gt.tag_name=%s AND gt.tag_revision=%s \
                 LIMIT 1"
        query_data = (git_path, tag_name, tag_rev)
        db_git_tag_id = get_value_from_query_data(query, query_data)
        if db_git_tag_id == 0:
            return

        query = "UPDATE git_tag SET deleted_by=%s, deleted_at=%s \
                 WHERE id=%s AND tag_name=%s AND tag_revision=%s \
                 LIMIT 1"
        query_data = (db_user_email_id, deleted_at, \
                      db_git_tag_id, tag_name, tag_rev)
        do_query(query, query_data)

    def update_git_tag_strict(self, \
                              db_git_commit_id=None, \
                              tag_name=None, \
                              tag_rev=None, \
                              tagger=None, \
                              tag_date=None, \
                              tag_message=None):

        if not self.is_connect():
            return

        if db_git_commit_id is None or tag_name is None or tag_rev is None \
            or tagger is None or tag_date is None or tag_message is None:
            return

        self.update_user_email(tagger)
        db_user_email_id = self.get_user_email_id(tagger)

        if db_user_email_id == 0:
            return

        db_git_tag_id = self.get_tag_id(db_git_commit_id, tag_name, tag_rev)

        if db_git_tag_id == 0:
            query = "INSERT INTO git_tag \
                     (git_commit_id, tag_name, tag_revision, \
                     tag_date, tag_message, tagger_id) \
                     VALUES(%s, %s, %s, %s, %s, %s)"
            query_data = (db_git_commit_id, tag_name, tag_rev, \
                          tag_date, tag_message, db_user_email_id)
            do_query(query, query_data)
        else:
            query = "UPDATE git_tag SET \
                     git_commit_id=%s, tag_name=%s, tag_revision=%s, \
                     tag_date=%s, tag_message=%s, tagger_id=%s \
                     WHERE (id=%s) \
                     AND (tag_date <> %s OR tag_message <> %s OR tagger_id <> %s)\
                     LIMIT 1"
            query_data = (db_git_commit_id, tag_name, tag_rev, \
                          tag_date, tag_message, db_user_email_id, db_git_tag_id, \
                          tag_date, tag_message, db_user_email_id)
            do_query(query, query_data)

    def get_obs_package_id(self, package_name):

        if not self.is_connect():
            return

        # Select id from git_repository
        query = "SELECT id FROM obs_package WHERE name = %s"
        query_data = (package_name,)

        return get_value_from_query_data(query, query_data)

    def update_obs_package(self, package_name):

        if not self.is_connect():
            return

        query = "INSERT INTO obs_package (name) SELECT * FROM (SELECT %s) AS tmp \
                 WHERE NOT EXISTS (SELECT name FROM obs_package WHERE name = %s) LIMIT 1"
        do_query(query, (package_name, package_name))


    def get_git_repo_for_manifest(self, build_project_id, git_repo=None):

        if not self.is_connect():
            return

        manifest_data = {}

        if git_repo:
            query = "SELECT gr.name, gc.commit_id, op.name FROM \
                     ( SELECT * FROM snapshot_manifest order by date desc) as sm, \
                     git_repository gr, git_commit gc, obs_package op \
                     WHERE sm.build_project_id = %s \
                     AND sm.git_repository_id = \
                     ( SELECT id FROM git_repository WHERE name = %s ) \
                     AND gr.id = sm.git_repository_id \
                     AND gc.id = sm.git_commit_id \
                     AND op.id = sm.obs_package_id \
                     GROUP BY gr.name"
            query_data = (build_project_id,git_repo)
        else:
            query = "SELECT gr.name, gc.commit_id, op.name FROM \
                     ( SELECT * FROM snapshot_manifest order by date desc) as sm, \
                     git_repository gr, git_commit gc, obs_package op \
                     WHERE sm.build_project_id = %s \
                     AND gr.id = sm.git_repository_id \
                     AND gc.id = sm.git_commit_id \
                     AND op.id = sm.obs_package_id \
                     GROUP BY gr.name"
            query_data = (build_project_id,)
        rows = get_multi_values_from_query_data(query, query_data)
        if len(rows) == 1 and rows[0] == 0:
            return manifest_data
        for x,y,z in rows:
            manifest = []
            manifest.append((y,z))
            manifest_data[x] = manifest
        # return data
        # {'git_repo': [(commit,obs_package)]}
        return manifest_data

    def get_obs_package_for_manifest(self, build_project_id, obs_package=None):

        if not self.is_connect():
            return

        manifest_data = {}

        if obs_package:
            query = "SELECT gr.name, gc.commit_id, op.name FROM \
                     ( SELECT * FROM snapshot_manifest order by date desc) as sm, \
                     git_repository gr, git_commit gc, obs_package op \
                     WHERE sm.build_project_id = %s \
                     AND sm.obs_package_id = \
                     ( SELECT id FROM obs_package WHERE name = %s ) \
                     AND gr.id = sm.git_repository_id \
                     AND gc.id = sm.git_commit_id \
                     AND op.id = sm.obs_package_id \
                     GROUP BY gr.name"
            query_data = (build_project_id, obs_package)

        else:
            query = "SELECT gr.name, gc.commit_id, op.name FROM \
                     ( SELECT * FROM snapshot_manifest order by date desc) as sm, \
                     git_repository gr, git_commit gc, obs_package op \
                     WHERE sm.build_project_id = %s \
                     AND gr.id = sm.git_repository_id \
                     AND gc.id = sm.git_commit_id \
                     AND op.id = sm.obs_package_id \
                     GROUP BY gr.name"
            query_data = (build_project_id,)
        rows = get_multi_values_from_query_data(query, query_data)
        if len(rows) == 1 and rows[0] == 0:
            return manifest_data
        for x,y,z in rows:
            manifest = []
            manifest.append((x,y))
            manifest_data[z] = manifest
        # return data
        # {'package': [(git_repo,commit)]}
        return manifest_data


    def is_contain_git_in_project(self, project, git_repo, package_name):

        if not self.is_connect():
            return [0,'']

        build_project_id = self.get_build_project_id(project)
        if build_project_id == 0:
            return [0,'']

        manifest_data = self.get_git_repo_for_manifest(build_project_id, git_repo)
        if not manifest_data.get(git_repo):
            manifest_data = self.get_obs_package_for_manifest(build_project_id, package_name)
            if not manifest_data.get(package_name):
                return [-1,'']

            gitrepo, _commit = manifest_data.get(package_name)[0]
            if git_repo != gitrepo:
                return [-2, gitrepo]
        else:
            _commit, obs_package_name = manifest_data.get(git_repo)[0]
            if package_name != obs_package_name:
                return [-2, obs_package_name]

        return [0,'']

    def update_manifest_bulkdata(self, manifest_data_bulk_data):

        if not self.is_connect():
            return

        query = "INSERT INTO snapshot_manifest (build_project_id, git_repository_id, git_commit_id, obs_package_id, date) VALUES \
                 (%s, %s, %s, %s, %s)"
        do_many_query(query, manifest_data_bulk_data)

    def update_sr_accept_log(self, profile, sr_tag, repa_user, comment, decision):

        if not self.is_connect():
            return

        # reject
        repa_decision_db = 'R'
        if decision == 'accept':
            repa_decision_db = 'A'
    
        query = "INSERT INTO sr_accept_log (sr, profile, repa_user, comment, decision, status) " \
                " VALUES(%s, %s, %s, %s, %s, 'R')"
        query_data = ( sr_tag, profile, repa_user, comment, repa_decision_db)
        do_query(query, query_data)

    def purge_snapshot_manifest_exist(self, build_project_id):

        if not self.is_connect():
            return

        query = "DELETE FROM snapshot_manifest WHERE build_project_id = %s"
        query_data = (build_project_id,)
        do_query(query, query_data)

    def update_project_mgr_log(self, id, error_string):

        if not self.is_connect():
            return

        if error_string is None or error_string == "":
            status = "succeeded"
            error_string = "None"
        else:
            status = "failed"
    
        query = "UPDATE project_mgr_log SET status=%s, reason=%s WHERE id=%s"
        query_data = ( status, error_string, id)
        do_query(query, query_data)

    def create_project_mgr_log(self, submitter, decision, project, package, comment, error_string):

        if not self.is_connect():
            return

        if error_string is None or error_string == "":
            status = "succeeded"
            error_string = "None"
        else:
            status = "failed"

        issue_time = str(datetime.now())
        if '::::' in comment and len(comment.split('::::')) == 2:
            comment, issue_time = comment.split('::::')
            if issue_time == 'None':
                issue_time = str(datetime.now())

        query = "INSERT INTO project_mgr_log (submitter, decision, project, package, " \
                " comment, status, reason, decision_at)" \
                " VALUES(%s, %s, %s, %s, %s, %s, %s, %s)"
        query_data = (submitter, decision, project, package, comment, status, error_string, issue_time)
        do_query(query, query_data)

    def get_build_repository_name_id(self, repo_name):

        if not self.is_connect():
            return

        if type(repo_name) == str:
            repo_name = [repo_name]

        param_count_str = ','.join(["%s"] * len(repo_name))
        query = "SELECT id, repository FROM build_repository_name WHERE repository IN (%s)" % param_count_str
        query_data = set(repo_name)
        rows = get_multi_values_from_query_data(query, query_data)

        ret_data = {}
        for x in rows:
            ret_data[str(x[1])] = int(x[0]) #pylint: disable=unsubscriptable-object

        return ret_data

    def update_build_repository_name(self, repo_name):

        if not self.is_connect():
            return

        if type(repo_name) == str:
            repo_name = [repo_name]

        rows = self.get_build_repository_name_id(repo_name)

        new_repo_name_list = copy.deepcopy(repo_name)
        for x in rows:
            new_repo_name_list.remove(x)

        query = "INSERT IGNORE INTO build_repository_name (repository) VALUES(%s)"
        query_list = []
        for x in new_repo_name_list:
            query_list.append((x,))
        do_many_query(query, query_list)

        return self.get_build_repository_name_id(repo_name)

    def get_build_arch_name_id(self, arch_name):

        if not self.is_connect():
            return

        if type(arch_name) == str:
            arch_name = [arch_name]

        param_count_str = ','.join(["%s"] * len(arch_name))
        query = "SELECT id, arch FROM build_arch_name WHERE arch IN (%s)" % param_count_str
        query_data = set(arch_name)
        rows = get_multi_values_from_query_data(query, query_data)

        ret_data = {}
        for x in rows:
            ret_data[str(x[1])] = int(x[0]) #pylint: disable=unsubscriptable-object

        return ret_data

    def update_build_arch_name(self, arch_name):

        if not self.is_connect():
            return

        if type(arch_name) == str:
            arch_name = [arch_name]

        rows = self.get_build_arch_name_id(arch_name)

        new_arch_name_list = copy.deepcopy(arch_name)
        for x in rows:
            new_arch_name_list.remove(x)

        query = "INSERT IGNORE INTO build_arch_name (arch) VALUES(%s)"
        query_list = []
        for x in new_arch_name_list:
            query_list.append((x,))
        do_many_query(query, query_list)

        return self.get_build_arch_name_id(arch_name)

    def get_device_name_id(self, device_name):

        if not self.is_connect():
            return

        if type(device_name) == str:
            device_name = [device_name]

        device_name = list(set(device_name))
        param_count_str = ','.join(["%s"] * len(device_name))
        query = "SELECT id, device_name FROM device_name WHERE device_name IN (%s)" % param_count_str
        query_data = set(device_name)
        rows = get_multi_values_from_query_data(query, query_data)

        ret_data = {}
        for x in rows:
            ret_data[str(x[1])] = int(x[0]) #pylint: disable=unsubscriptable-object

        return ret_data

    def update_device_name(self, device_name):

        if not self.is_connect():
            return

        if type(device_name) == str:
            device_name = [device_name]

        rows = self.get_device_name_id(device_name)

        new_device_name_list = copy.deepcopy(device_name)
        for x in rows:
            new_device_name_list.remove(x)

        query = "INSERT IGNORE INTO device_name (device_name) VALUES(%s)"
        query_list = []
        for x in new_device_name_list:
            query_list.append((x,))
        do_many_query(query, query_list)

        return self.get_device_name_id(device_name)

    def update_gbm2pin_git_sync_history(self, id, log, error_string=None):

        if not self.is_connect():
            return

        if error_string is None or error_string == "":
            status = "succeeded"
        else:
            status = "failed"
            print "Err:%s" %(error_string)

        query = "UPDATE gbm2spin_sync_history SET log=%s, status=%s WHERE id=%s"
        query_data = ( log, status, id)
        do_query(query, query_data)

class GbsDashboard(BuildMonitorExtention):

    gbs_stage_lookup = [
        "queued",
        "build_started",
        "build_finished",
        "snapshot_started",
        "snapshot_finished",
        "image_started",
        "image_finished",
        "test_started",
        "test_finished",
        "completed"]

    def __init__(self):

        BuildMonitorExtention.__init__(self)

    def set_queue(self, tag, main_project, source_snapshot, gbs_type, submitter):

        self.update_user_email(submitter)

        query = "INSERT INTO gbs_status (tag, project_name_id, build_snapshot_id, \
                  gbs_type_id, gbs_submitter_id) \
                 SELECT * FROM (SELECT (%s), \
                  (SELECT id FROM main_project WHERE name=%s), \
                  (SELECT id FROM build_snapshot WHERE snapshot_name=%s), \
                  (SELECT id FROM gbs_type_lookup WHERE category=%s), \
                  (SELECT id FROM user_email WHERE email=%s)) AS tmp \
                 WHERE NOT EXISTS (SELECT id FROM gbs_status WHERE tag=%s) LIMIT 1"
        query_data = (tag, main_project, source_snapshot, gbs_type, submitter, tag)
        do_query(query, query_data)

    def set_stage(self, tag, stage, reason=None, timestamp=None, worker={}):

        assert type(reason) == dict

        if reason is None or reason == "":
            reason = {"status": ""}

        if  reason.get("status") == "S":
            reason["status"] = "succeeded"
        elif  reason.get("status") == "F":
            reason["status"] = "failed"

        assert timestamp is not None

        misc_info = dict(reason.items() + worker.items())

        query = "INSERT INTO gbs_stage (gbs_status_id, gbs_stage_id, stage_status, record_date, misc_info) \
                 SELECT * FROM ( \
                  (SELECT id FROM gbs_status WHERE tag=%s) AS tmp1, \
                  (SELECT id FROM gbs_stage_lookup WHERE stage=%s) AS tmp2, \
                  (SELECT (%s)) AS tmp3, \
                  (SELECT (%s)) AS tmp4, \
                  (SELECT (%s)) AS tmp5) \
                 LIMIT 1"
        query_data = (tag, stage, reason.get("status",""), timestamp, "%s" % misc_info)
        do_query(query, query_data)

    def set_packages(self, tag, packages):

        if packages is None:
            return

        for x in packages:
            git_path = x.keys()[0]
            commit_id = x[git_path].get('commit')
            include_build = x[git_path].get('build')
            include_image = x[git_path].get('image')

            if commit_id is None or commit_id == "":
                commit_id = "-"

            self.update_repository(git_path)
            db_git_path_id = self.get_repository_id(git_path)
            self.update_commit(db_git_path_id, commit_id, str(datetime.now()))

            if include_build == "include" and include_image == "include":
                include_mode = "BO_IO"
            elif include_build == "include" and include_image == "exclude":
                include_mode = "BO_IX"
            elif include_build == "exclude" and include_image == "exclude":
                include_mode = "BX_IX"
            else:
                assert False

            query = "INSERT INTO gbs_commit (gbs_status_id, git_commit_id, git_commit_mode_id) \
                     SELECT * FROM ( \
                      (SELECT id FROM gbs_status WHERE tag=%s) AS tmp1, \
                      (SELECT gc.id FROM git_commit gc, git_repository gr WHERE gr.name=%s \
                        AND gr.id=gc.git_repository_id AND gc.commit_id=%s ORDER BY gc.id DESC LIMIT 1) AS tmp2, \
                      (SELECT id FROM gbs_commit_mode_lookup WHERE mode=%s) AS tmp3) \
                     WHERE NOT EXISTS ( \
                      SELECT gc.id FROM gbs_commit gc, gbs_status gs, git_commit gitc, git_repository gr \
                       WHERE gs.tag=%s AND gs.id=gc.gbs_status_id AND gc.git_commit_id=gitc.id \
                       AND gitc.git_repository_id=gr.id AND gr.name=%s AND gitc.commit_id=%s) \
                     LIMIT 1"
            query_data = (tag, git_path, commit_id, include_mode, tag, git_path, commit_id)
            do_query(query, query_data)

    def release_snapshot(self, tag, release_type, version, comment, url, submitter):

        query = "INSERT INTO gbs_release (gbs_status_id, release_type_id, release_name, \
                  release_url, comment, released_by) \
                 SELECT * FROM ( \
                  (SELECT id FROM gbs_status WHERE tag=%s) AS tmp1, \
                  (SELECT id FROM gbs_release_type_lookup WHERE release_type=%s) AS tmp2, \
                  (SELECT (%s)) AS tmp3, \
                  (SELECT (%s)) AS tmp4, \
                  (SELECT (%s)) AS tmp5, \
                  (SELECT id FROM user_email WHERE email=%s) AS tmp6) \
                 LIMIT 1"
        query_data = (tag, release_type, version, url, comment, submitter)
        do_query(query, query_data)

def put_snapshot_manifest(bm_ext, snapshot_name, manifest_items, start_datetime):
    """
       PUT Snapshot Manifest
    """
    # bulk data
    # INSERT INTO TABLE_A (A, B, C, D) VALUES
    # (1,1,1,1),
    # (2,2,2,2),
    # (3,3,3,3),
    # (4,4,4,4);
    if not bm_ext.enabled:
        print "Skip Put snapshot manifest..."
        return False

    build_project_id = bm_ext.get_build_project_id_for_buildsnapshot(snapshot_name)
    if build_project_id == 0:
        return False

    #Delete data after check
    bm_ext.purge_snapshot_manifest_exist(build_project_id)

    manifest_data = []
    # getid from git_repository
    for git_repo, git_commit, obs_name in manifest_items:

        bm_ext.update_repository(git_repo)
        git_repository_id = bm_ext.get_repository_id(git_repo)
        
        bm_ext.update_commit(git_repository_id, git_commit, start_datetime)
        git_commit_id = bm_ext.get_commit_id(git_repository_id, git_commit)

        bm_ext.update_obs_package(obs_name)
        obs_pkg_name_id = bm_ext.get_obs_package_id(obs_name)
        manifest_data.append((build_project_id, git_repository_id, git_commit_id, obs_pkg_name_id, start_datetime))
     
    bm_ext.update_manifest_bulkdata(manifest_data)

def get_snapshot_manifest(bm_ext, project):
    """
    Get snapshot manifest
    """
    manifest_list = []
    
    if not bm_ext.enabled:
        print "Skip Get snapshot manifest..."
        return

    build_project_id = bm_ext.get_build_project_id(project)
   
    manifest_list = bm_ext.get_manifest(build_project_id)

    return manifest_list

