#!/usr/bin/env python
# vim: expandtab

# Copyright (C) 2011-2018 Jelmer Vernooij <jelmer@jelmer.uk>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""Tests for the git remote helper."""

from __future__ import absolute_import

from io import BytesIO
import os

from dulwich.repo import Repo

from ....tests import (
    TestCaseWithTransport,
    TestSkipped,
    )

from ..object_store import get_object_store
from ..git_remote_helper import (
    RemoteHelper,
    open_local_dir,
    fastexporter,
    fetch,
    )


def map_to_git_sha1(dir, bzr_revid):
    object_store = get_object_store(dir.open_repository())
    with object_store.lock_read():
        return object_store._lookup_revision_sha1(bzr_revid)


class OpenLocalDirTests(TestCaseWithTransport):

    def test_from_env_dir(self):
        self.make_branch_and_tree('bla', format='git')
        self.overrideEnv('GIT_DIR', os.path.join(self.test_dir, 'bla', '.git'))
        open_local_dir()

    def test_from_dir(self):
        self.make_branch_and_tree('.', format='git')
        open_local_dir()


class FetchTests(TestCaseWithTransport):

    def setUp(self):
        super(FetchTests, self).setUp()
        self.local_dir = self.make_branch_and_tree('local', format='git').controldir
        self.remote_tree = self.make_branch_and_tree('remote')
        self.remote_dir = self.remote_tree.controldir
        self.shortname = 'bzr'

    def fetch(self, wants):
        outf = BytesIO()
        fetch(outf, wants, self.shortname, self.remote_dir, self.local_dir)
        return outf.getvalue()

    def test_no_wants(self):
        r = self.fetch([])
        self.assertEqual(b"\n", r)

    def test_simple(self):
        self.build_tree(['remote/foo'])
        self.remote_tree.add("foo")
        revid = self.remote_tree.commit("msg")
        git_sha1 = map_to_git_sha1(self.remote_dir, revid)
        out = self.fetch([(git_sha1, 'HEAD')])
        self.assertEqual(out, b"\n")
        r = Repo('local')
        self.assertTrue(git_sha1 in r.object_store)
        self.assertEqual({
            }, r.get_refs())


class RemoteHelperTests(TestCaseWithTransport):

    def setUp(self):
        super(RemoteHelperTests, self).setUp()
        self.local_dir = self.make_branch_and_tree('local', format='git').controldir
        self.remote_tree = self.make_branch_and_tree('remote')
        self.remote_dir = self.remote_tree.controldir
        self.shortname = 'bzr'
        self.helper = RemoteHelper(self.local_dir, self.shortname, self.remote_dir)

    def test_capabilities(self):
        f = BytesIO()
        self.helper.cmd_capabilities(f, [])
        capabs = f.getvalue()
        base = b"fetch\noption\npush\n"
        self.assertTrue(capabs in (base+b"\n", base+b"import\n\n"), capabs)

    def test_option(self):
        f = BytesIO()
        self.helper.cmd_option(f, [])
        self.assertEqual(b"unsupported\n", f.getvalue())

    def test_list_basic(self):
        f = BytesIO()
        self.helper.cmd_list(f, [])
        self.assertEqual(
            b'\n',
            f.getvalue())

    def test_import(self):
        if fastexporter is None:
            raise TestSkipped("bzr-fastimport not available")
        self.build_tree_contents([("remote/afile", b"somecontent")])
        self.remote_tree.add(["afile"])
        self.remote_tree.commit(b"A commit message", timestamp=1330445983,
            timezone=0, committer=b'Somebody <jrandom@example.com>')
        f = BytesIO()
        self.helper.cmd_import(f, ["import", b"refs/heads/master"])
        self.assertEqual(
            b'commit refs/heads/master\n'
            b'mark :1\n'
            b'committer Somebody <jrandom@example.com> 1330445983 +0000\n'
            b'data 16\n'
            b'A commit message\n'
            b'M 644 inline afile\n'
            b'data 11\n'
            b'somecontent\n',
            f.getvalue())
