# Copyright 2016 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import itertools
import re

from recipe_engine import recipe_api

class GitApi(recipe_api.RecipeApi):
    """GitApi provides support for Git."""

    _GIT_HASH_RE = re.compile('[0-9a-f]{40}', re.IGNORECASE)

    def __init__(self, *args, **kwargs):
        super(GitApi, self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        """Return a git command step."""
        name = kwargs.pop('name', 'git ' + args[0])
        infra_step = kwargs.pop('infra_step', True)
        if 'cwd' not in kwargs:
            kwargs.setdefault('cwd', self.m.path['checkout'])
        git_cmd = ['git']
        options = kwargs.pop('config_options', {})
        for k, v in sorted(options.iteritems()):
            git_cmd.extend(['-c', '%s=%s' % (k, v)])
        return self.m.step(name, git_cmd + list(args), **kwargs)

    def checkout(self, url, path=None, ref=None, remote=None, file=None, **kwargs):
        """Checkout a given ref and return the checked out revision."""
        if not path:
            path = url.rsplit('/', 1)[-1]
            if path.endswith('.git'):  # https://host/foobar.git
                path = path[:-len('.git')]
            path = path or path.rsplit('/', 1)[-1] # ssh://host:repo/foobar/.git
            path = self.m.path['start_dir'].join(path)

        if 'checkout' not in self.m.path:
            self.m.path['checkout'] = path

        if not self.m.path.exists(path):
            self.m.shutil.makedirs('makedirs', path)

        if self.m.path.exists(path.join('.git')): # pragma: no cover
            self('config', '--remove-section', 'remote.%s' % remote, **kwargs)
        else:
            self('init', path, **kwargs)
        self('remote', 'add', remote or 'origin', url)

        if not ref:
            fetch_ref = self.m.properties.get('branch') or 'master'
            checkout_ref = 'FETCH_HEAD'
        elif self._GIT_HASH_RE.match(ref):
            fetch_ref = ''
            checkout_ref = ref
        elif ref.startswith('refs/heads/'):
            fetch_ref = ref[len('refs/heads/'):]
            checkout_ref = 'FETCH_HEAD'
        else:
            fetch_ref = ref
            checkout_ref = 'FETCH_HEAD'
        fetch_args = [x for x in (remote, fetch_ref) if x]
        self('fetch', *fetch_args, **kwargs)
        if file:
            self('checkout', '-f', checkout_ref, '--', file, **kwargs)
        else:
            self('checkout', '-f', checkout_ref, **kwargs)
        step = self('rev-parse', 'HEAD', stdout=self.m.raw_io.output(),
                    step_test_data=lambda:
                        self.m.raw_io.test_api.stream_output('deadbeef'))
        self('clean', '-f', '-d', '-x', **kwargs)
        return step.stdout.strip()

    def get_hash(self, commit='HEAD', **kwargs):
        """Find and return the hash of the given commit."""
        return self('show', commit, '--format=%H', '-s',
                    step_test_data=lambda:
                        self.m.raw_io.test_api.stream_output('deadbeef'),
                    stdout=self.m.raw_io.output(), **kwargs).stdout.strip()

    def get_timestamp(self, commit='HEAD', test_data=None, **kwargs):
        """Find and return the timestamp of the given commit."""
        return self('show', commit, '--format=%at', '-s',
                    step_test_data=lambda:
                        self.m.raw_io.test_api.stream_output('1473312770'),
                    stdout=self.m.raw_io.output(), **kwargs).stdout.strip()
