#! /usr/bin/python
import logging, mox, os, shutil, tempfile, utils
from autotest_lib.client.common_lib import revision_control


class GitRepoManager(object):
    """
    A wrapper for GitRepo.
    """
    commit_hash = None
    commit_msg = None
    repodir = None
    git_repo_manager = None


    def __init__(self, master_repo=None):
        """
        Setup self.git_repo_manager.

        If a master_repo is present clone it.
        Otherwise create a directory in /tmp and init it.

        @param master_repo: GitRepo representing master.
        """
        if master_repo is None:
            self.repodir = tempfile.mktemp(suffix='master')
            self._create_git_repo(self.repodir)
            self.git_repo_manager = revision_control.GitRepo(
                                        self.repodir,
                                        self.repodir,
                                        abs_work_tree=self.repodir)
        else:
            self.repodir = tempfile.mktemp(suffix='dependent')
            self.git_repo_manager = revision_control.GitRepo(
                                      self.repodir,
                                      master_repo.repodir,
                                      abs_work_tree=self.repodir)
            self.git_repo_manager.clone()


    def _edit(self, filename='foo', msg='bar'):
        """
        Write msg into a file in the repodir.

        @param filename: Name of the file in current repo.
                If none exists one will be created.
        @param msg: A message to write into the file.
        """
        local_file_name = os.path.join(self.git_repo_manager.repodir,
                                       filename)
        with open(local_file_name, 'w') as f:
            f.write(msg)


    def _create_git_repo(self, repodir):
        """
        Init a new git repository.

        @param repodir: directory for repo.
        """
        logging.info('initializing git repo in: %s', repodir)
        gitcmd = 'git init %s' % repodir
        rv = utils.run(gitcmd)
        if rv.exit_status != 0:
            logging.error(rv.stderr)
            raise revision_control.revision_control.GitError(gitcmd+' failed')


    def add(self):
        """
        Add all unadded files in repodir to repo.
        """
        rv = self.git_repo_manager.gitcmd('add .')
        if rv.exit_status != 0:
            logging.error(rv.stderr)
            raise revision_control.GitError('Unable to add files to repo', rv)


    def commit(self, msg='default'):
        """
        Commit changes to repo with the supplied commit msg.
        Also updates commit_hash with the hash for this commit.

        @param msg: A message that goes with the commit.
        """
        self.git_repo_manager.commit(msg)
        self.commit_hash = self.git_repo_manager.get_latest_commit_hash()


    def get_master_tot(self):
        """
        Get everything from masters TOT squashing local changes.
        If the dependent repo is empty pull from master.
        """
        self.git_repo_manager.pull_or_clone()
        self.commit_hash = self.git_repo_manager.get_latest_commit_hash()


class RevisionControlUnittest(mox.MoxTestBase):
    """
    A unittest to exercise build_externals.py's usage
    of revision_control.py's Git wrappers.
    """
    master_repo=None
    dependent_repo=None

    def setUp(self):
        """
        Create a master repo and clone it into a dependent repo.
        """
        super(RevisionControlUnittest, self).setUp()
        self.master_repo = GitRepoManager()
        self.dependent_repo = GitRepoManager(self.master_repo)


    def tearDown(self):
        """
        Delete temporary directories.
        """
        shutil.rmtree(self.master_repo.repodir)
        shutil.rmtree(self.dependent_repo.repodir)
        super(RevisionControlUnittest, self).tearDown()


    def testCommit(self):
        """
        Test add, commit, pull, clone.
        """
        self.master_repo._edit()
        self.master_repo.add()
        self.master_repo.commit()
        self.dependent_repo.get_master_tot()
        self.assertEquals(self.dependent_repo.commit_hash,
            self.master_repo.commit_hash,
            msg=(("hashes don't match after clone, master and dependent repo"
                  "out of sync: %r != %r") %
                  (self.dependent_repo.commit_hash,
                   self.master_repo.commit_hash)))

        self.master_repo._edit(msg='foobar')
        self.master_repo.commit()
        self.dependent_repo.get_master_tot()
        self.assertEquals(self.dependent_repo.commit_hash,
            self.master_repo.commit_hash,
            msg=(("hashes don't match after pull, master and dependent repo"
                  "out of sync: %r != %r") %
                  (self.dependent_repo.commit_hash,
                   self.master_repo.commit_hash)))


    def testGitUrlClone(self):
        """
        Test that git clone raises a ValueError if giturl is unset.
        """
        self.dependent_repo.git_repo_manager._giturl = None
        self.mox.StubOutWithMock(revision_control.GitRepo,
            'is_repo_initialized')
        self.dependent_repo.git_repo_manager.is_repo_initialized().AndReturn(
            False)
        self.mox.ReplayAll()

        self.assertRaises(ValueError,
                  self.dependent_repo.git_repo_manager.pull_or_clone)


    def testGitUrlPull(self):
        """
        Test that git pull raises a ValueError if giturl is unset.
        """
        self.dependent_repo.git_repo_manager._giturl = None
        self.mox.StubOutWithMock(revision_control.GitRepo,
            'is_repo_initialized')
        self.dependent_repo.git_repo_manager.is_repo_initialized().AndReturn(
            True)
        self.mox.ReplayAll()

        self.assertRaises(ValueError,
                  self.dependent_repo.git_repo_manager.pull_or_clone)


    def testGitUrlFetch(self):
        """
        Test that git fetch raises a ValueError if giturl is unset.
        """
        self.dependent_repo.git_repo_manager._giturl = None
        self.mox.StubOutWithMock(revision_control.GitRepo,
            'is_repo_initialized')
        self.dependent_repo.git_repo_manager.is_repo_initialized().AndReturn(
            True)
        self.mox.ReplayAll()

        self.assertRaises(ValueError,
                  self.dependent_repo.git_repo_manager.pull_or_clone)
