#! /usr/bin/env python
# Copyright (C) 2011 OpenStack, LLC.
# Copyright (c) 2012 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

# manage_projects.py reads a project config file called projects.yaml
# It should look like:

# - homepage: http://openstack.org
#   gerrit-host: review.openstack.org
#   local-git-dir: /var/lib/git
#   gerrit-key: /home/gerrit2/review_site/etc/ssh_host_rsa_key
#   has-wiki: False
#   has-issues: False
#   has-downloads: False
# ---
# - project: PROJECT_NAME
#   options:
#    - has-wiki
#    - has-issues
#    - has-downloads
#    - has-pull-requests
#   homepage: Some homepage that isn't http://openstack.org
#   description: This is a great project
#   remote: https://gerrit.googlesource.com/gerrit
#   upstream: git://github.com/bushy/beards.git
#   acl_config: /path/to/gerrit/project.config


import ConfigParser
import logging
import os
import re
import shlex
import subprocess
import tempfile
import yaml

import github
import gerritlib.gerrit

logging.basicConfig(level=logging.ERROR)
log = logging.getLogger("manage_projects")


def run_command(cmd, status=False, env={}):
    cmd_list = shlex.split(str(cmd))
    newenv = os.environ
    newenv.update(env)
    log.debug("Executing command: %s" % " ".join(cmd_list))
    p = subprocess.Popen(cmd_list, stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT, env=newenv)
    (out, nothing) = p.communicate()
    log.debug("Return code: %s" % p.returncode)
    log.debug("Command said: %s" % out.strip())
    if status:
        return (p.returncode, out.strip())
    return out.strip()


def run_command_status(cmd, env={}):
    return run_command(cmd, True, env)


def git_command(repo_dir, sub_cmd, env={}):
    git_dir = os.path.join(repo_dir, '.git')
    cmd = "git --git-dir=%s --work-tree=%s %s" % (git_dir, repo_dir, sub_cmd)
    status, _ = run_command(cmd, True, env)
    return status


def git_command_output(repo_dir, sub_cmd, env={}):
    git_dir = os.path.join(repo_dir, '.git')
    cmd = "git --git-dir=%s --work-tree=%s %s" % (git_dir, repo_dir, sub_cmd)
    status, out = run_command(cmd, True, env)
    return (status, out)


def fetch_config(project, remote_url, repo_path, env={}):
    status = git_command(repo_path, "fetch %s +refs/meta/config:"
                         "refs/remotes/gerrit-meta/config" % remote_url, env)
    if status != 0:
        print "Failed to fetch refs/meta/config for project: %s" % project
        return False
    # Because the following fails if executed more than once you should only
    # run fetch_config once in each repo.
    status = git_command(repo_path, "checkout -b config "
                         "remotes/gerrit-meta/config")
    if status != 0:
        print "Failed to checkout config for project: %s" % project
        return False

    return True


def copy_acl_config(project, repo_path, acl_config):
    if not os.path.exists(acl_config):
        return False

    acl_dest = os.path.join(repo_path, "project.config")
    status, _ = run_command("cp %s %s" %
                            (acl_config, acl_dest), status=True)
    if status == 0:
        status = git_command(repo_path, "diff-index --quiet HEAD --")
        if status != 0:
            return True
    return False


def push_acl_config(project, remote_url, repo_path, env={}):
    cmd = "commit -a -m'Update project config.' --author='Openstack Project " \
          "Creator <openstack-infra@lists.openstack.org>'"
    status = git_command(repo_path, cmd)
    if status != 0:
        print "Failed to commit config for project: %s" % project
        return False
    status, out = git_command_output(repo_path,
                                     "push %s HEAD:refs/meta/config" %
                                     remote_url, env)
    if status != 0:
        print "Failed to push config for project: %s" % project
        print out
        return False
    return True


def _get_group_uuid(gerrit, group):
    query = "select group_uuid from account_groups where name = '%s'" % group
    data = gerrit.dbQuery(query)
    if data:
        for row in data:
            if row["type"] == "row":
                return row["columns"]["group_uuid"]
    return None


def get_group_uuid(gerrit, group):
    uuid = _get_group_uuid(gerrit, group)
    if uuid:
        return uuid
    gerrit.createGroup(group)
    uuid = _get_group_uuid(gerrit, group)
    if uuid:
        return uuid
    return None


def create_groups_file(project, gerrit, repo_path):
    acl_config = os.path.join(repo_path, "project.config")
    group_file = os.path.join(repo_path, "groups")
    uuids = {}
    for line in open(acl_config, 'r'):
        r = re.match(r'^\s+.*group\s+(.*)$', line)
        if r:
            group = r.group(1)
            if group in uuids.keys():
                continue
            uuid = get_group_uuid(gerrit, group)
            if uuid:
                uuids[group] = uuid
            else:
                return False
    if uuids:
        with open(group_file, 'w') as fp:
            for group, uuid in uuids.items():
                fp.write("%s\t%s\n" % (uuid, group))
    status = git_command(repo_path, "add groups")
    if status != 0:
        print "Failed to add groups file for project: %s" % project
        return False
    return True


def make_ssh_wrapper(gerrit_user, gerrit_key):
    (fd, name) = tempfile.mkstemp(text=True)
    os.write(fd, '#!/bin/bash\n')
    os.write(fd,
             'ssh -i %s -l %s -o "StrictHostKeyChecking no" $@\n' %
             (gerrit_key, gerrit_user))
    os.close(fd)
    os.chmod(name, 755)
    return dict(GIT_SSH=name)


def main():

    PROJECTS_YAML = os.environ.get('PROJECTS_YAML',
                                   '/home/gerrit2/projects.yaml')
    configs = [config for config in yaml.load_all(open(PROJECTS_YAML))]
    defaults = configs[0][0]
    default_has_issues = defaults.get('has-issues', False)
    default_has_downloads = defaults.get('has-downloads', False)
    default_has_wiki = defaults.get('has-wiki', False)

    LOCAL_GIT_DIR = defaults.get('local-git-dir', '/var/lib/git')
    GERRIT_HOST = defaults.get('gerrit-host')
    GERRIT_USER = defaults.get('gerrit-user')
    GERRIT_KEY = defaults.get('gerrit-key')

    GITHUB_SECURE_CONFIG = defaults.get(
        'github-config',
        '/etc/github/github-projects.secure.config')

    secure_config = ConfigParser.ConfigParser()
    secure_config.read(GITHUB_SECURE_CONFIG)

    # Project creation doesn't work via oauth
    ghub = github.Github(secure_config.get("github", "username"),
                         secure_config.get("github", "password"))
    orgs = ghub.get_user().get_orgs()
    orgs_dict = dict(zip([o.login.lower() for o in orgs], orgs))

    gerrit = gerritlib.gerrit.Gerrit('localhost',
                                     GERRIT_USER,
                                     29418,
                                     GERRIT_KEY)
    project_list = gerrit.listProjects()
    ssh_env = make_ssh_wrapper(GERRIT_USER, GERRIT_KEY)
    try:

        for section in configs[1]:
            project = section['project']
            options = section.get('options', dict())
            description = section.get('description', None)
            homepage = section.get('homepage', defaults.get('homepage', None))
            upstream = section.get('upstream', None)

            project_git = "%s.git" % project
            project_dir = os.path.join(LOCAL_GIT_DIR, project_git)

            # Find the project's repo
            project_split = project.split('/', 1)
            if len(project_split) > 1:
                repo_name = project_split[1]
            else:
                repo_name = project
            has_issues = 'has-issues' in options or default_has_issues
            has_downloads = 'has-downloads' in options or default_has_downloads
            has_wiki = 'has-wiki' in options or default_has_wiki
            try:
                org = orgs_dict[project_split[0].lower()]
            except KeyError:
                # We do not have control of this github org ignore the project.
                continue
            try:
                repo = org.get_repo(repo_name)
            except github.GithubException:
                repo = org.create_repo(repo_name,
                                       homepage=homepage,
                                       has_issues=has_issues,
                                       has_downloads=has_downloads,
                                       has_wiki=has_wiki)
            if description:
                repo.edit(repo_name, description=description)
            if homepage:
                repo.edit(repo_name, homepage=homepage)

            repo.edit(repo_name, has_issues=has_issues,
                      has_downloads=has_downloads,
                      has_wiki=has_wiki)

            if 'gerrit' not in [team.name for team in repo.get_teams()]:
                teams = org.get_teams()
                teams_dict = dict(zip([t.name.lower() for t in teams], teams))
                teams_dict['gerrit'].add_to_repos(repo)

            remote_url = "ssh://localhost:29418/%s" % project
            if project not in project_list:
                tmpdir = tempfile.mkdtemp()
                try:
                    repo_path = os.path.join(tmpdir, 'repo')
                    if upstream:
                        run_command("git clone %(upstream)s %(repo_path)s" %
                                    dict(upstream=upstream,
                                         repo_path=repo_path))
                    else:
                        run_command("git init %s" % repo_path)
                        with open(os.path.join(repo_path,
                                               ".gitreview"),
                                  'w') as gitreview:
                            gitreview.write("""
    [gerrit]
    host=%s
    port=29418
    project=%s
    """ % (GERRIT_HOST, project_git))
                        git_command(repo_path, "add .gitreview")
                        cmd = "commit -a -m'Added .gitreview' --author=" \
                              "'Openstack Project Creator " \
                              "<openstack-infra@lists.openstack.org>'"
                        git_command(repo_path, cmd)
                    gerrit.createProject(project)

                    if not os.path.exists(project_dir):
                        run_command("git --bare init %s" % project_dir)
                        run_command("chown -R gerrit2:gerrit2 %s"
                                    % project_dir)

                    git_command(repo_path,
                                "push --all %s" % remote_url,
                                env=ssh_env)
                    git_command(repo_path,
                                "push --tags %s" % remote_url, env=ssh_env)
                finally:
                    run_command("rm -fr %s" % tmpdir)

            if 'acl_config' in section:
                tmpdir = tempfile.mkdtemp()
                try:
                    repo_path = os.path.join(tmpdir, 'repo')
                    ret, _ = run_command_status("git init %s" % repo_path)
                    if ret != 0:
                        continue
                    if (fetch_config(project,
                                     remote_url,
                                     repo_path,
                                     ssh_env) and
                        copy_acl_config(project, repo_path,
                                        section['acl_config']) and
                            create_groups_file(project, gerrit, repo_path)):
                        push_acl_config(project,
                                        remote_url,
                                        repo_path,
                                        ssh_env)
                finally:
                    run_command("rm -fr %s" % tmpdir)
    finally:
        os.unlink(ssh_env['GIT_SSH'])
