import argparse
import logging
import os
import re
import shutil
from subprocess import CalledProcessError
import sys
from gitubuntu.__main__ import top_level_defaults
from gitubuntu.git_repository import (
    GitUbuntuRepository,
    GitUbuntuRepositoryFetchError,
)
from gitubuntu.run import decode_binary, run

import pkg_resources
import pygit2

def copy_hooks(src, dst):
    try:
        os.mkdir(dst)
    except FileExistsError:
        pass

    for hook in os.listdir(src):
        shutil.copy2(
            os.path.join(src, hook),
            dst,
        )

def main(
    package,
    directory=None,
    lp_user=None,
    proto=top_level_defaults.proto,
):
    """Entry point to clone subcommand

    @package: Name of source package
    @directory: directory to clone the repository into
    @lp_user: user to authenticate to Launchpad as
    @proto: string protocol to use (one of 'http', 'https', 'git')

    If directory is None, a relative directory with the same name as
    package will be used.

    If lp_user is None, value of `git config gitubuntu.lpuser` will be
    used.

    Returns the resulting GitUbuntuRepository object, if successful;
    None otherwise.
    """
    directory = (
        os.path.abspath(directory)
        if directory
        else os.path.join(os.path.abspath(os.getcwd()), package)
    )
    if os.path.isdir(directory):
        logging.error('directory %s exists' % directory)
        return None

    local_repo = GitUbuntuRepository(
        local_dir=directory,
        lp_user=lp_user,
        fetch_proto=proto,
    )

    copy_hooks(
        pkg_resources.resource_filename(
           'gitubuntu',
           'hooks',
        ),
        os.path.join(
            directory,
            os.getenv('GIT_DIR', '.git'),
            'hooks',
        ),
    )

    local_repo.add_base_remotes(package)
    try:
        local_repo.fetch_base_remotes(verbose=True)
    except GitUbuntuRepositoryFetchError:
        logging.error("Unable to find an imported repository for %s. "
            "Please request an import by e-mailing "
            "ubuntu-distributed-devel@lists.ubuntu.com.",
            package
        )
        shutil.rmtree(local_repo.local_dir)
        return None

    local_repo.add_lpuser_remote(pkgname=package)
    logging.debug("added remote '%s' -> %s", local_repo.lp_user,
        local_repo.raw_repo.remotes[local_repo.lp_user].url
    )
    try:
        local_repo.fetch_lpuser_remote(verbose=True)
    except GitUbuntuRepositoryFetchError:
        pass

    try:
        local_repo.create_tracking_branch(
            local_branch_name='ubuntu/devel',
            remote_name='pkg',
            remote_branch_name='ubuntu/devel',
        )
        local_repo.checkout_commitish('ubuntu/devel')
    except:
        logging.error('Unable to checkout ubuntu/devel, does '
            'pkg/ubuntu/devel branch exist?'
        )

    local_repo.git_run(['config', 'notes.displayRef', 'refs/notes/changelog'])

    if os.path.isfile(os.path.join(directory, '.gitignore')):
        logging.warning('A .gitignore file exists in the source '
            'package. This will affect the behavior of git. Consider '
            'backing up the gitignore while working on this package '
            'to ensure all changes are tracked or passing appropriate '
            'flags to git commands (e.g., git status --ignored).'
        )

    return local_repo

def parse_args(subparsers=None, base_subparsers=None):
    kwargs = dict(
        description='Clone a source package git repository to a directory',
        formatter_class=argparse.RawTextHelpFormatter,
        epilog='''
Example:
   * clone to open-iscsi/
     %(prog)s open-iscsi
   * clone to ubuntu.git
     %(prog)s open-iscsi ubuntu.git
   * use git rather than https protocol for remotes:
     %(prog)s --proto=git open-iscsi
'''
                 )
    if base_subparsers:
        kwargs['parents'] = base_subparsers
    if subparsers:
        parser = subparsers.add_parser('clone', **kwargs)
        parser.set_defaults(func=cli_main)
    else:
        parser = argparse.ArgumentParser(**kwargs)
    parser.add_argument('package', type=str,
        help='Name of source package to clone'
    )
    parser.add_argument('directory', type=str,
        help='Local directory to clone to. If not specified, a '
             ' directory with the same name as PACKAGE will be '
             'used',
        default=None,
        nargs='?'
    )
    parser.add_argument('-l', '--lp-user', type=str, help=argparse.SUPPRESS)
    if not subparsers:
        return parser.parse_args()
    return 'clone - %s' % kwargs['description']

def cli_main(args):
    try:
        lp_user = args.lp_user
    except AttributeError:
        lp_user = None

    if main(
        package=args.package,
        directory=args.directory,
        lp_user=lp_user,
        proto=args.proto,
    ) is not None:
        return 0
    return 1


# vi: ts=4 expandtab
