#!/usr/bin/env python
#
# Copyright (c) 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.
#
"""
"""

import os
import sys
import json
import base64
import re

from datetime import datetime
from time import sleep
from common.buildtrigger import trigger_info

from common.buildmonitor_extention import GbsDashboard

###########################
#### STATE TRANSISTION ####
###########################
#  1 - queued    (queued)
#  2 - build_0   (build_queued)
#  3 - build_1   (build_started)
#  4 - build_2   (build_finished)
#  5 - repo_0    (snapshot_queued)
#  6 - repo_1    (snapshot_started)
#  7 - repo_2    (snapshot_finished)
#  8 - image_0   (image_queued)
#  9 - image_1   (image_started)
# 10 - image_2   (image_finished)
# 11 - test_0    (test_queued)
# 12 - test_1    (test_started)
# 13 - test_2    (test_finished)
# 14 - completed (completed)
###########################

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

def update_reason_lookup(gbs_inst, data):
    for k, v in data.iteritems():
        if k == "repo":
            data[k] = int(gbs_inst.update_build_repository_name(data[k])[data[k]])
        elif k == "arch":
            data[k] = int(gbs_inst.update_build_arch_name(data[k])[data[k]])
        elif k == "ks_name":
            data[k] = int(gbs_inst.update_device_name(data[k])[data[k]])
        elif k == "ks_name_list":
            ret_dict = gbs_inst.update_device_name(data[k])
            data[k] = ",".join(str(e) for e in ret_dict.values())
        elif k == "repo_arch_list":
            repo_arch_map = {}
            for x in v:
                if x["repo"] not in repo_arch_map:
                    repo_arch_map[x["repo"]] = []
                repo_arch_map[x["repo"]].append(x["arch"])
            ret_repos = gbs_inst.update_build_repository_name(repo_arch_map.keys())
            index_str = ""
            for x in repo_arch_map:
                if index_str is not None and index_str != "":
                    index_str += "|"
                index_str += str(ret_repos[x]) + "-"
                ret_archs = gbs_inst.update_build_arch_name(repo_arch_map[x])
                index_str += ",".join(str(e) for e in ret_archs.values())
            data[k] = index_str

def _set_stage(gbs_inst, stage, content):

    if type(content.get('reason')) == dict:
        update_reason_lookup(gbs_inst, content.get('reason'))
    else:
        content['reason'] = {'status': content.get('reason', '')}

    gbs_inst.set_stage(
                       content.get('tag'),
                       stage,
                       content.get('reason'),
                       content.get('_timestamp'),
                       content.get('_worker', {})
                       )

def fn_queued(gbs_inst, content):
    tag             = content.get('tag')
    main_project    = content.get('main_project')
    source_snapshot = content.get('source_snapshot')
    gbs_type        = content.get('gbs_type')
    submitter       = content.get('submitter', 'tizen.build@samsung.com')
    packages        = content.get('packages')

    # set_queue() should be done by Dashboard itself when user initiate it.
    # Call one more time here for confirmation.
    gbs_inst.set_queue(tag, main_project, source_snapshot, gbs_type, submitter)

    _set_stage(gbs_inst, "queued", content)
    gbs_inst.set_packages(tag, packages)

def fn_build_queued(gbs_inst, content):
    _set_stage(gbs_inst, "build_0", content)
    return

def fn_build_started(gbs_inst, content):
    _set_stage(gbs_inst, "build_1", content)
    return

def fn_build_finished(gbs_inst, content):
    _set_stage(gbs_inst, "build_2", content)
    return

def fn_snapshot_queued(gbs_inst, content):
    _set_stage(gbs_inst, "repo_0", content)
    return

def fn_snapshot_started(gbs_inst, content):
    _set_stage(gbs_inst, "repo_1", content)
    return

def fn_snapshot_finished(gbs_inst, content):
    _set_stage(gbs_inst, "repo_2", content)
    return

def fn_image_queued(gbs_inst, content):
    _set_stage(gbs_inst, "image_0", content)
    return

def fn_image_started(gbs_inst, content):
    _set_stage(gbs_inst, "image_1", content)
    return

def fn_image_finished(gbs_inst, content):
    _set_stage(gbs_inst, "image_2", content)
    return

def fn_test_queued(gbs_inst, content):
    _set_stage(gbs_inst, "test_0", content)
    return

def fn_test_started(gbs_inst, content):
    _set_stage(gbs_inst, "test_1", content)
    return

def fn_test_finished(gbs_inst, content):
    _set_stage(gbs_inst, "test_2", content)
    return

def fn_completed(gbs_inst, content):
    _set_stage(gbs_inst, "completed", content)
    return

def fn_abort(gbs_inst, content):
    _set_stage(gbs_inst, "aborted", content)
    return

def fn_release_snapshot(gbs_inst, content):
    gbs_inst.release_snapshot(
                       content.get('tag'),
                       content.get('release_type'),
                       content.get('version'),
                       content.get('comment'),
                       content.get('url'),
                       content.get('submitter')
                       )
    return

def fn_default(gbs_inst, content):
    assert False

def main():

    gbs_inst = GbsDashboard()
    content = trigger_info(os.getenv('TRIGGER_INFO'))

    callback_func_table = {
        "queued"           : fn_queued,
        "build_queued"     : fn_build_queued,
        "build_started"    : fn_build_started,
        "build_finished"   : fn_build_finished,
        "snapshot_queued"  : fn_snapshot_queued,
        "snapshot_started" : fn_snapshot_started,
        "snapshot_finished": fn_snapshot_finished,
        "image_queued"     : fn_image_queued,
        "image_started"    : fn_image_started,
        "image_finished"   : fn_image_finished,
        "test_queued"      : fn_test_queued,
        "test_started"     : fn_test_started,
        "test_finished"    : fn_test_finished,
        "completed"        : fn_completed,
        "aborted"          : fn_abort,
        "release_snapshot" : fn_release_snapshot,
        "default"          : fn_default
    }

    callback_func_table[content.get('mode', 'default')](gbs_inst, content)

if __name__ == '__main__':
    try:
        sys.exit(main())
    except LocalError, err:
        sys.exit(1)

