#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4
#
# Copyright (C) 2016 Samsung
#
#    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.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#

import subprocess
import os
import json

from common.utils import sync

#================================================================================
# get_domain_group
#================================================================================
def get_domain_group(g):
    sp = g.split(' - ')
    if len(sp) != 2:
        return '', '', ''

    domain = sp[0]
    subdomain = ""
    group = sp[1]

    sp = domain.split(' / ')
    if len(sp) == 2:
        domain = sp[0]
        subdomain = sp[1]

    return domain, subdomain, group

#================================================================================
# get_groups
#================================================================================
def get_groups():
    cmd = "ssh -p %s %s@%s gerrit ls-groups" % \
      (os.getenv('GERRIT_SSHPORT', 29418), os.getenv('GERRIT_USERNAME'), os.getenv('GERRIT_HOSTNAME', "review.tizen.org"))
    popen = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (stdoutdata, stderrdata) = popen.communicate()

    return stdoutdata.strip().split('\n')

#================================================================================
# get_projects
#================================================================================
def get_projects():
    cmd = "ssh -p %s %s@%s gerrit ls-projects --format json -t -b master -b refs/meta/config " % \
      (os.getenv('GERRIT_SSHPORT', 29418), os.getenv('GERRIT_USERNAME'), os.getenv('GERRIT_HOSTNAME', "review.tizen.org"))
    popen = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (stdoutdata, stderrdata) = popen.communicate()

    return json.loads(stdoutdata)

#================================================================================
# get_group_members()
#================================================================================
def get_group_members(g):
    g = g.replace(' ', '\ ')
    cmd = "ssh -p %s %s@%s gerrit ls-members \"%s\""%\
      (os.getenv('GERRIT_SSHPORT', 29418), os.getenv('GERRIT_USERNAME'), os.getenv('GERRIT_HOSTNAME', "review.tizen.org"), g)
    popen = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (stdoutdata, stderrdata) = popen.communicate()

    members = []
    for l in stdoutdata.strip().split('\n'):
        sp = l.strip().split('\t')
        if sp[3] != "email":
            members.append(sp[3])
    return members

#================================================================================
# make_acl_to_domain()
#================================================================================
def make_acl_to_domain(domain_user_map):
    acl_to_domain = {}
    for domain in domain_user_map:
        dc = domain.replace("&","and").replace(" ","_").lower()
        domain_converted = "scm/acls/domain_"+dc
        acl_to_domain[domain_converted] = (domain, '')
        for subdomain in domain_user_map[domain]:
            sdc = subdomain.replace("&","and").replace(" ","_").lower()
            domain_converted = "scm/acls/domain_"+dc+"/"+sdc
            acl_to_domain[domain_converted] = (domain, subdomain)
    return acl_to_domain

#================================================================================
# generate_domain_user_map()
#================================================================================
def generate_domain_user_map():
    domain_user_map = {}
    git_user_map = {}
    git_domain_map = {}

    groups = get_groups()

    for g in groups:
        domain, subdomain, group = get_domain_group(g)

        if len(domain) == 0:
            continue
        members = get_group_members(g)

        if domain not in domain_user_map:
            domain_user_map[domain] = {}
        if subdomain not in domain_user_map[domain]:
            domain_user_map[domain][subdomain] = {}
        if group not in domain_user_map[domain][subdomain]:
            domain_user_map[domain][subdomain][group] = []

        domain_user_map[domain][subdomain][group].extend(members)

    acl_to_domain = make_acl_to_domain(domain_user_map)

    j = get_projects()
    for p in j:
        try:
            if "parent" not in j[p]:
                print "No parent field in %s" % p
                continue
            (domain, subdomain) = acl_to_domain[j[p]["parent"]]
            if "projects" not in domain_user_map[domain][subdomain]:
                domain_user_map[domain][subdomain]["projects"] = []
            domain_user_map[domain][subdomain]["projects"].append(p)

            for g in domain_user_map[domain][subdomain]:
                if g == "projects":
                    continue
                if p not in git_user_map:
                    git_user_map[p] = {}
                    git_domain_map[p] = {}
                git_user_map[p][g] = domain_user_map[domain][subdomain][g]
                git_domain_map[p] = [domain, subdomain]
        except KeyError:
            print "Failed to find acl_to_domain. project=%s, acl=%s" % (p, j[p]["parent"])

    return domain_user_map, git_user_map, git_domain_map

#================================================================================
# make_domain_user_map_array()
#================================================================================
def make_domain_user_map_array(domain_user_map):
    domain_user_map_array = []
    for d in domain_user_map:
        for sd in domain_user_map[d]:
            A = []
            M = []
            I = []
            R = []
            if "Architects" in domain_user_map[d][sd]:
                A = domain_user_map[d][sd]["Architects"]
            if "Maintainers" in domain_user_map[d][sd]:
                M = domain_user_map[d][sd]["Maintainers"]
            if "Integrators" in domain_user_map[d][sd]:
                I = domain_user_map[d][sd]["Integrators"]
            if "Reviewers" in domain_user_map[d][sd]:
                R = domain_user_map[d][sd]["Reviewers"]

            if "projects" in domain_user_map[d][sd]:
                for g in domain_user_map[d][sd]["projects"]:
                    di = {"domain":d, "subdomain":sd, "p":g, "A":A, "M":M, "I":I, "R":R}
                    domain_user_map_array.append(di)
            else:
                print "projects not found in domain (%s/%s)" % (d, sd)

    return domain_user_map_array

#================================================================================
# print_to_file()
#================================================================================
def print_to_file(filename, dict):
    with open(filename, "w") as f:
      f.write(json.dumps(dict))

#================================================================================
# generate_mapping()
#================================================================================
def generate_mapping(target_dir):

    if not os.path.exists(target_dir):
        os.makedirs(target_dir)

    domain_user_map, git_user_map, git_domain_map = generate_domain_user_map()
    f = "/".join([target_dir,"domain_user_map.json"])
    print_to_file(f, domain_user_map)

    f = "/".join([target_dir,"git_user_map.json"])
    print_to_file(f, git_user_map)

    f = "/".join([target_dir,"git_domain_map.json"])
    print_to_file(f, git_domain_map)

    domain_user_map_array = make_domain_user_map_array(domain_user_map)
    f = "/".join([target_dir,"domain_user_map_array.json"])
    print_to_file(f, domain_user_map_array)

###########################################################
# test

#target_dir = ".dashboard/git_domain"
#
#generate_mapping(target_dir)
#exit(0)

###########################################################
# main
target_dir = ".dashboard/git_domain"

generate_mapping(target_dir)

sync_dest = os.path.join(os.getenv("IMG_SYNC_DEST_BASE"), "snapshots", target_dir)
# sync to the download server.
ret = sync(target_dir, sync_dest)
if ret != 0:
    raise Exception("rsync failed. ret_code=%d"%ret)

