from __future__ import unicode_literals

import os

import appdirs

from reviewbot.config import config
from reviewbot.utils.api import get_api_root
from reviewbot.utils.filesystem import make_tempdir
from reviewbot.utils.log import get_logger
from reviewbot.utils.process import execute


logger = get_logger(__name__)


repositories = {}


class Repository(object):
    """A repository."""

    def sync(self):
        """Sync the latest state of the repository."""
        pass


class GitRepository(Repository):
    """A git repository."""

    def __init__(self, name, clone_path):
        """Initialize the repository.

        Args:
            name (unicode):
                The configured name of the repository.

            clone_path (unicode):
                The path of the git remote to clone.
        """
        self.name = name
        self.clone_path = clone_path
        self.repo_path = os.path.join(appdirs.site_data_dir('reviewbot'),
                                      'repositories', name)

    def sync(self):
        """Sync the latest state of the repository."""
        if not os.path.exists(self.repo_path):
            os.makedirs(self.repo_path)

            logger.info('Cloning repository %s to %s',
                        self.clone_path, self.repo_path)
            execute(['git', 'clone', '--bare', self.clone_path,
                     self.repo_path])
        else:
            logger.info('Fetching into existing repository %s',
                        self.repo_path)
            execute(['git', '--git-dir=%s' % self.repo_path, 'fetch',
                     'origin', '+refs/heads/*:refs/heads/*', '--prune'])

    def checkout(self, commit_id):
        """Check out the given commit.

        Args:
            commit_id (unicode):
                The ID of the commit to check out.

        Returns:
            unicode:
            The name of a directory with the given checkout.
        """
        workdir = make_tempdir()
        branchname = 'br-%s' % commit_id

        logger.info('Creating temporary branch for clone in repo %s',
                    self.repo_path)
        execute(['git', '--git-dir=%s' % self.repo_path, 'branch', branchname,
                 commit_id])

        logger.info('Creating working tree for commit ID %s in %s', commit_id,
                    workdir)
        execute(['git', 'clone', '--local', '--no-hardlinks', '--depth', '1',
                 '--branch', branchname, self.repo_path, workdir])

        logger.info('Removing temporary branch for clone in repo %s',
                    self.repo_path)
        execute(['git', '--git-dir=%s' % self.repo_path, 'branch', '-d',
                 branchname])

        return workdir


class HgRepository(Repository):
    """A hg repository."""

    def __init__(self, name, clone_path):
        """Initialize the repository.