#! /usr/bin/env python
# Copyright (C) 2011 OpenStack Foundation
# 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 config file called projects.ini
# It should look like:
#
# [projects]
# homepage=https://opendev.org
# acl-dir=/home/gerrit2/acls
# local-git-dir=/opt/lib/git
# jeepyb-cache-dir=/opt/lib/jeepyb
# gerrit-host=review.opendev.org
# gerrit-user=project-creator
# gerrit-committer=Project Creator <project-creator@opendev.org>
# gerrit-key=/home/gerrit2/review_site/etc/ssh_project_rsa_key
# has-github=false
#
# manage_projects.py reads a project listing file called projects.yaml
# It should look like:
# - project: PROJECT_NAME
#   options:
#    - has-wiki
#    - has-issues
#    - has-downloads
#    - has-pull-requests
#    - track-upstream
#   homepage: Some homepage that isn't http://opendev.org
#   description: This is a great project
#   upstream: https://gerrit.googlesource.com/gerrit
#   upstream-prefix: upstream
#   acl-config: /path/to/gerrit/project.config
#   acl-append:
#     - /path/to/gerrit/project.config
#   acl-parameters:
#     project: OTHER_PROJECT_NAME

import argparse
from six.moves import configparser
import glob
import hashlib
import json
import logging
import os
import re
import shutil
import sys
import time

import gerritlib.gerrit
import github

import jeepyb.log
import jeepyb.utils as u

registry = u.ProjectsRegistry()

log = logging.getLogger("manage_projects")
orgs = None

# Gerrit system groups as defined:
# https://review.opendev.org/Documentation/access-control.html#system_groups
# Need to set Gerrit system group's uuid to the format it expects.
GERRIT_SYSTEM_GROUPS = {
    'Anonymous Users': 'global:Anonymous-Users',
    'Project Owners': 'global:Project-Owners',
    'Registered Users': 'global:Registered-Users',
    'Change Owner': 'global:Change-Owner',
}


class FetchConfigException(Exception):
    pass


class CopyACLException(Exception):
    pass


class ProcessACLException(Exception):
    pass


class PushToGerritException(Exception):
    pass


class CreateGroupException(Exception):
    pass


def fetch_config(project, remote_url, repo_path, env=None):
    env = env or {}
    # Poll for refs/meta/config as gerrit may not have written it out for
    # us yet.
    for x in range(10):
        status = u.git_command(
            repo_path,
            "fetch %s +refs/meta/config:refs/remotes/gerrit-meta/config"
            % remote_url, env)
        if status == 0:
            break
        else:
            log.debug("Failed to fetch refs/meta/config for project: %s" %
                      project)
            time.sleep(2)
    if status != 0:
        log.error("Failed to fetch refs/meta/config for project: %s" % project)
        raise FetchConfigException()

    # Poll for project.config as gerrit may not have committed an empty
    # one yet.
    output = ""
    for x in range(10):
        status = u.git_command(repo_path, "remote update --prune", env)
        if status != 0:
            log.error("Failed to update remote: %s" % remote_url)
            time.sleep(2)
            continue
        else:
            status, output = u.git_command_output(
                repo_path, "ls-files --with-tree=remotes/gerrit-meta/config "
                           "project.config", env)
        if output.strip() != "project.config" or status != 0:
            log.debug("Failed to find project.config for project: %s" %
                      project)
            time.sleep(2)
        else:
            break
    if output.strip() != "project.config" or status != 0:
        log.error("Failed to find project.config for project: %s" % project)
        raise FetchConfigException()

    # Because the following fails if executed more than once you should only
    # run fetch_config once in each repo.
    status = u.git_command(
        repo_path, "checkout -B config remotes/gerrit-meta/config")
    if status != 0:
        log.error("Failed to checkout config for project: %s" % project)
        raise FetchConfigException()


def copy_acl_config(project, repo_path, acl_config):
    if not os.path.exists(acl_config):
        raise CopyACLException()

    acl_dest = os.path.join(repo_path, "project.config")
    status, _ = u.run_command(
        "cp %s %s" % (acl_config, acl_dest), status=True)
    if status != 0:
        raise CopyACLException()

    status = u.git_command(repo_path, "diff --quiet")
    return status != 0


def push_acl_config(project, remote_url, repo_path, gitid, env=None):
    env = env or {}
    cmd = "commit -a -m'Update project config.' --author='%s'" % gitid
    status, out = u.git_command_output(repo_path, cmd)
    if status != 0:
        log.error("Failed to commit config for project: %s" % project)
        log.error(out)
        return False
    status, out = u.git_command_output(
        repo_path, "push %s HEAD:refs/meta/config" % remote_url, env)
    if status != 0:
        log.error("Failed to push config for project: %s" % project)
        log.error(out)
        return False
    return True


def _get_group_uuid(gerrit, group, retries=10):
    """
    Gerrit keeps internal user groups in the DB while it keeps systems
    groups in All-Projects groups file (in refs/meta/config).  This
    will only get the UUIDs for internal user groups.

    Note: 'Administrators', 'Non-Interactive Users' and all other custom
    groups in Gerrit are defined as internal user groups.

    Wait for up to 10 seconds for the group to be created in the DB.
    """
    for x in range(retries):
        # Work around gerritlib raising a generic "Exception" exception
        # when listGroup() finds no group
        try:
            group_list = list(gerrit.listGroup(group, verbose=True))
        except Exception:
            group_list = None
        if group_list:
            return group_list[0].split('\t')[1]
        if retries > 1:
            time.sleep(1)
    return None


def get_group_uuid(gerrit, group):
    uuid = _get_group_uuid(gerrit, group, retries=1)
    if uuid:
        return uuid
    if group in GERRIT_SYSTEM_GROUPS:
        return GERRIT_SYSTEM_GROUPS[group]
    gerrit.createGroup(group)
    for user in list(gerrit.listMembers(group)):
        if gerrit.connection.username == user['username']:
            # Gerrit now adds creating user to groups. We don't want that.
            gerrit.removeMember(group, gerrit.connection.username)
            break
    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'^.*\sgroup\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:
                log.error("Unable to get UUID for group %s." % group)
                raise CreateGroupException()
    if uuids:
        with open(group_file, 'w') as fp:
            for group, uuid in uuids.items():
                fp.write("%s\t%s\n" % (uuid, group))
        status = u.git_command(repo_path, "add groups")
        if status != 0:
            log.error("Failed to add groups file for project: %s" % project)
            raise CreateGroupException()


def create_update_github_project(
        default_has_issues, default_has_downloads, default_has_wiki,
        github_secure_config, options, project, description, homepage,
        cache):
    created = False
    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

    needs_update = False
    if not cache.get('created-in-github', False):
        needs_update = True
    if not cache.get('gerrit-in-team', False):
        needs_update = True
    if cache.get('has_issues', default_has_issues) != has_issues:
        needs_update = True
    if cache.get('has_downloads', default_has_downloads) != has_downloads:
        needs_update = True
    if cache.get('has_wiki', default_has_wiki) != has_wiki:
        needs_update = True
    if not needs_update:
        return False

    secure_config = configparser.ConfigParser()
    secure_config.read(github_secure_config)

    global orgs
    if orgs is None:
        if secure_config.has_option("github", "oauth_token"):
            ghub = github.Github(secure_config.get("github", "oauth_token"))
        else:
            ghub = github.Github(secure_config.get("github", "username"),
                                 secure_config.get("github", "password"))

        log.info('Fetching github org list')
        orgs = ghub.get_user().get_orgs()
    orgs_dict = dict(zip([o.login.lower() for o in orgs], orgs))

    # Find the project's repo
    project_split = project.split('/', 1)
    org_name = project_split[0]
    if len(project_split) > 1:
        repo_name = project_split[1]
    else:
        repo_name = project

    try:
        org = orgs_dict[org_name.lower()]
    except KeyError:
        # We do not have control of this github org ignore the project.
        return False

    try:
        log.info("Fetching github info about %s", repo_name)
        repo = org.get_repo(repo_name)

    except github.GithubException:
        log.info("Creating %s in github", repo_name)
        repo = org.create_repo(repo_name,
                               homepage=homepage,
                               has_issues=has_issues,
                               has_downloads=has_downloads,
                               has_wiki=has_wiki)
        created = True

    cache['has_wiki'] = has_wiki
    cache['has_downloads'] = has_downloads
    cache['has_issues'] = has_issues

    kwargs = {}
    # If necessary, update project on Github
    if description and description != repo.description:
        kwargs['description'] = description
    if homepage and homepage != repo.homepage:
        kwargs['homepage'] = homepage
    if has_issues != repo.has_issues:
        kwargs['has_issues'] = has_issues
    if has_downloads != repo.has_downloads:
        kwargs['has_downloads'] = has_downloads
    if has_wiki != repo.has_wiki:
        kwargs['has_wiki'] = has_wiki

    if kwargs:
        log.info("Updating github repo info about %s", repo_name)
        repo.edit(repo_name, **kwargs)
    cache.update(kwargs)

    if not cache.get('gerrit-in-team', False):
        if 'gerrit' not in [team.name for team in repo.get_teams()]:
            log.info("Adding gerrit to github team for %s", repo_name)
            teams = org.get_teams()
            teams_dict = dict(zip([t.name.lower() for t in teams], teams))
            teams_dict['gerrit'].add_to_repos(repo)
        cache['gerrit-in-team'] = True
        created = True

    return created


# TODO(mordred): Inspect repo_dir:default-branch for a description
#                override
def find_description_override(repo_path):
    return None


def push_to_gerrit(repo_path, project, push_string, remote_url, ssh_env):
    try:
        u.git_command(repo_path, push_string % remote_url, env=ssh_env)
        u.git_command(repo_path, "push --tags %s" % remote_url, env=ssh_env)
    except Exception:
        log.exception(
            "Error pushing %s to Gerrit." % project)
        raise PushToGerritException()


def process_acls(acl_config, project, ACL_DIR, section,
                 remote_url, repo_path, ssh_env, gerrit, GERRIT_GITID):
    if not os.path.isfile(acl_config):
        return
    try:
        fetch_config(project, remote_url, repo_path, ssh_env)
        if not copy_acl_config(project, repo_path, acl_config):
            # nothing was copied, so we're done
            return
        create_groups_file(project, gerrit, repo_path)
        push_acl_config(project, remote_url, repo_path,
                        GERRIT_GITID, ssh_env)
    except Exception:
        log.exception(
            "Exception processing ACLS for %s." % project)
        raise ProcessACLException()
    finally:
        u.git_command(repo_path, 'reset --hard')
        default_branch = section.get('default-branch', 'master')
        u.git_command(repo_path, 'checkout %s' % default_branch)
        u.git_command(repo_path, 'branch -D config')


def create_gerrit_project(project, default_branch, project_list, gerrit):
    if project not in project_list:
        try:
            gerrit.createProject(project, branches=[default_branch])
            return True
        except Exception:
            log.exception(
                "Exception creating %s in Gerrit." % project)
            raise
    return False


def create_local_mirror(local_git_dir, project_git,
                        gerrit_system_user, gerrit_system_group):
    git_mirror_path = os.path.join(local_git_dir, project_git)
    if not os.path.exists(git_mirror_path):
        (ret, output) = u.run_command_status(
            "git --bare init %s" % git_mirror_path)
        if ret:
            u.run_command("rm -rf git_mirror_path")
            raise Exception(output)
        u.run_command(
            "chown -R %s:%s %s" % (
                gerrit_system_user, gerrit_system_group, git_mirror_path))


def main():
    parser = argparse.ArgumentParser(description='Manage projects')
    jeepyb.log.setup_logging_arguments(parser)
    parser.add_argument('--nocleanup', action='store_true',
                        help='do not remove temp directories')
    parser.add_argument('projects', metavar='project', nargs='*',
                        help='name of project(s) to process')
    args = parser.parse_args()
    jeepyb.log.configure_logging(args)

    default_has_github = registry.get_defaults('has-github', True)

    LOCAL_GIT_DIR = registry.get_defaults('local-git-dir', None)
    JEEPYB_CACHE_DIR = registry.get_defaults('jeepyb-cache-dir',
                                             '/var/lib/jeepyb')
    ACL_DIR = registry.get_defaults('acl-dir')
    GERRIT_HOST = registry.get_defaults('gerrit-host')
    GITREVIEW_GERRIT_HOST = registry.get_defaults(
        'gitreview-gerrit-host', GERRIT_HOST)
    GERRIT_PORT = int(registry.get_defaults('gerrit-port', '29418'))
    GITREVIEW_GERRIT_PORT = int(registry.get_defaults(
        'gitreview-gerrit-port', GERRIT_PORT))
    GERRIT_USER = registry.get_defaults('gerrit-user')
    GERRIT_KEY = registry.get_defaults('gerrit-key')
    GERRIT_GITID = registry.get_defaults('gerrit-committer')
    GERRIT_REPLICATE = registry.get_defaults('gerrit-replicate', True)
    GERRIT_OS_SYSTEM_USER = registry.get_defaults('gerrit-system-user',
                                                  'gerrit2')
    GERRIT_OS_SYSTEM_GROUP = registry.get_defaults('gerrit-system-group',
                                                   'gerrit2')
    DEFAULT_HOMEPAGE = registry.get_defaults('homepage')
    DEFAULT_HAS_ISSUES = registry.get_defaults('has-issues', False)
    DEFAULT_HAS_DOWNLOADS = registry.get_defaults('has-downloads', False)
    DEFAULT_HAS_WIKI = registry.get_defaults('has-wiki', False)
    GITHUB_SECURE_CONFIG = registry.get_defaults(
        'github-config',
        '/etc/github/github-projects.secure.config')
    PROJECT_CACHE_FILE = os.path.join(JEEPYB_CACHE_DIR, 'project.cache')
    project_cache = {}
    if os.path.exists(PROJECT_CACHE_FILE):
        project_cache = json.loads(open(PROJECT_CACHE_FILE, 'r').read())
    acl_cache = {}
    for acl_file in glob.glob(os.path.join(ACL_DIR, '*/*.config')):
        sha256 = hashlib.sha256()
        sha256.update(open(acl_file, 'r').read().encode('utf-8'))
        acl_cache[acl_file] = sha256.hexdigest()

    gerrit = gerritlib.gerrit.Gerrit(GERRIT_HOST,
                                     GERRIT_USER,
                                     GERRIT_PORT,
                                     GERRIT_KEY)
    project_list = list(gerrit.listProjects())
    ssh_env = u.make_ssh_wrapper(GERRIT_USER, GERRIT_KEY)
    try:
        # Collect processed errors,if any
        process_errors = []
        for section in registry.all_configs_list:
            project = section['project']
            if args.projects and project not in args.projects:
                continue

            try:
                log.info("Processing project: %s" % project)

                # Figure out all of the options
                options = section.get('options', dict())
                description = section.get('description', None)
                homepage = section.get('homepage', DEFAULT_HOMEPAGE)
                upstream = section.get('upstream', None)
                default_branch = section.get('default-branch', 'master')
                repo_path = os.path.join(JEEPYB_CACHE_DIR, project)

                # If this project doesn't want to use gerrit, exit cleanly.
                if 'no-gerrit' in options:
                    continue

                project_git = "%s.git" % project
                remote_url = "ssh://%s:%s/%s" % (
                    GERRIT_HOST,
                    GERRIT_PORT,
                    project)
                git_opts = dict(upstream=upstream,
                                repo_path=repo_path,
                                remote_url=remote_url)
                acl_config = section.get(
                    'acl-config',
                    '%s.config' % os.path.join(ACL_DIR, project))
                project_cache.setdefault(project, {})

                # Create the project in Gerrit first, since it will fail
                # spectacularly if its project directory or local replica
                # already exist on disk
                project_created = project_cache[project].get(
                    'project-created', False)
                if not project_created:
                    try:
                        project_created = create_gerrit_project(
                            project, default_branch, project_list, gerrit)
                        project_cache[project]['project-created'] = True
                    except Exception:
                        project_cache[project]['project-created'] = False
                        continue

                pushed_to_gerrit = project_cache[project].get(
                    'pushed-to-gerrit', False)
                if not pushed_to_gerrit:
                    # We haven't pushed to gerrit, so grab the repo again
                    if os.path.exists(repo_path):
                        shutil.rmtree(repo_path)

                    # Make Local repo
                    push_string = u.make_local_copy(
                        repo_path, project, default_branch, project_list,
                        git_opts, ssh_env, upstream, GITREVIEW_GERRIT_HOST,
                        GITREVIEW_GERRIT_PORT, project_git, GERRIT_GITID)

                    description = (
                        find_description_override(repo_path)
                        or description)

                    u.fsck_repo(repo_path)

                    if push_string:
                        push_to_gerrit(
                            repo_path, project, push_string,
                            remote_url, ssh_env)
                    project_cache[project]['pushed-to-gerrit'] = True
                    if GERRIT_REPLICATE:
                        gerrit.replicate(project)

                # Create the repo for the local git mirror
                if LOCAL_GIT_DIR:
                    # This is conditional because new gerrit url pathing
                    # has made local git mirrors less straightfoward.
                    create_local_mirror(
                        LOCAL_GIT_DIR, project_git,
                        GERRIT_OS_SYSTEM_USER, GERRIT_OS_SYSTEM_GROUP)

                if acl_config:
                    acl_sha = acl_cache.get(acl_config)
                    if project_cache[project].get('acl-sha') != acl_sha:

                        if not os.path.exists(repo_path):
                            u.make_local_copy(
                                repo_path, project, default_branch,
                                project_list, git_opts, ssh_env, upstream,
                                GERRIT_HOST, GERRIT_PORT, project_git,
                                GERRIT_GITID)
                        process_acls(
                            acl_config, project, ACL_DIR, section,
                            remote_url, repo_path, ssh_env, gerrit,
                            GERRIT_GITID)
                        project_cache[project]['acl-sha'] = acl_sha
                    else:
                        log.info("%s has matching sha, skipping ACLs",
                                 project)

                if 'has-github' in options or default_has_github:
                    created = create_update_github_project(
                        DEFAULT_HAS_ISSUES, DEFAULT_HAS_DOWNLOADS,
                        DEFAULT_HAS_WIKI, GITHUB_SECURE_CONFIG,
                        options, project, description, homepage,
                        project_cache[project])
                    if created and GERRIT_REPLICATE:
                        gerrit.replicate(project)
                    project_cache[project]['created-in-github'] = created

            except Exception:
                msg = "Problems creating %s, moving on." % project
                log.exception(msg)
                process_errors.append(msg)
                continue
            finally:
                # Clean up after ourselves - this repo has no use
                if os.path.exists(repo_path):
                    shutil.rmtree(repo_path)
    finally:
        with open(PROJECT_CACHE_FILE, 'w') as cache_out:
            log.info("Writing cache file %s", PROJECT_CACHE_FILE)
            cache_out.write(json.dumps(
                project_cache, sort_keys=True, indent=2))
        os.unlink(ssh_env['GIT_SSH'])
        if len(process_errors) > 0:
            log.error("%d problems has been caught during run:\n %s" % (
                len(process_errors), process_errors))
            sys.exit(1)


if __name__ == "__main__":
    main()
