#  Copyright (C) 2017 Codethink Limited
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2 of the License, or (at your option) any later version.
#
#  This library 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
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
#
#  Authors:
#        Jonathan Maw <jonathan.maw@codethink.co.uk>

"""
bzr - stage files from a bazaar repository
==========================================

**Host dependencies:**

  * bzr

**Usage:**

.. code:: yaml

   # Specify the bzr source kind
   kind: bzr

   # Specify the bzr url. Bazaar URLs come in many forms, see
   # `bzr help urlspec` for more information. Using an alias defined
   # in your project configuration is encouraged.
   url: https://launchpad.net/bzr

   # Specify the tracking branch. This is mandatory, as bzr cannot identify
   # an individual revision outside its branch. bzr URLs that omit the branch
   # name implicitly specify the trunk branch, but bst requires this to be
   # explicit.
   track: trunk

   # Specify the ref. This is a revision number. This is usually a decimal,
   # but revisions on a branch are of the form
   # <revision-branched-from>.<branch-number>.<revision-since-branching>
   # e.g. 6622.1.6.
   # The ref must be specified to build, and 'bst source track' will update the
   # revision number to the one on the tip of the branch specified in 'track'.
   ref: 6622

See :ref:`built-in functionality doumentation <core_source_builtins>` for
details on common configuration options for sources.
"""

import os
import shutil
import fcntl
from contextlib import contextmanager

from buildstream import Source, SourceError, Consistency
from buildstream import utils


class BzrSource(Source):
    # pylint: disable=attribute-defined-outside-init

    def configure(self, node):
        self.node_validate(node, ['url', 'track', 'ref', *Source.COMMON_CONFIG_KEYS])

        self.original_url = self.node_get_member(node, str, 'url')
        self.tracking = self.node_get_member(node, str, 'track')
        self.ref = self.node_get_member(node, str, 'ref', None)
        self.url = self.translate_url(self.original_url)

    def preflight(self):
        # Check if bzr is installed, get the binary at the same time.
        self.host_bzr = utils.get_host_tool('bzr')

    def get_unique_key(self):
        return [self.original_url, self.tracking, self.ref]

    def get_consistency(self):
        if self.ref is None or self.tracking is None:
            return Consistency.INCONSISTENT

        # Lock for the _check_ref()
        with self._locked():
            if self._check_ref():
                return Consistency.CACHED
            else:
                return Consistency.RESOLVED

    def load_ref(self, node):
        self.ref = self.node_get_member(node, str, 'ref', None)

    def get_ref(self):
        return self.ref

    def set_ref(self, ref, node):
        node['ref'] = self.ref = ref

    def track(self):
        with self.timed_activity("Tracking {}".format(self.url),
                                 silent_nested=True), self._locked():
            self._ensure_mirror(skip_ref_check=True)
            ret, out = self.check_output([self.host_bzr, "version-info",
                                          "--custom", "--template={revno}",
                                          self._get_branch_dir()],
                                         fail="Failed to read the revision number at '{}'"
                                         .format(self._get_branch_dir()))
            if ret != 0:
                raise SourceError("{}: Failed to get ref for tracking {}".format(self, self.tracking))

            return out

    def fetch(self):
        with self.timed_activity("Fetching {}".format(self.url),
                                 silent_nested=True), self._locked():
            self._ensure_mirror()

    def stage(self, directory):
        self.call([self.host_bzr, "checkout", "--lightweight",
                   "--revision=revno:{}".format(self.ref),
                   self._get_branch_dir(), directory],
                  fail="Failed to checkout revision {} from branch {} to {}"
                  .format(self.ref, self._get_branch_dir(), directory))
        # Remove .bzr dir
        shutil.rmtree(os.path.join(directory, ".bzr"))

    def init_workspace(self, directory):
        url = os.path.join(self.url, self.tracking)
        with self.timed_activity('Setting up workspace "{}"'.format(directory), silent_nested=True):
            # Checkout from the cache
            self.call([self.host_bzr, "branch",
                       "--use-existing-dir",
                       "--revision=revno:{}".format(self.ref),
                       self._get_branch_dir(), directory],
                      fail="Failed to branch revision {} from branch {} to {}"
                      .format(self.ref, self._get_branch_dir(), directory))
            # Switch the parent branch to the source's origin
            self.call([self.host_bzr, "switch",
                       "--directory={}".format(directory), url],
                      fail="Failed to switch workspace's parent branch to {}".format(url))

    # _locked()
    #
    # This context manager ensures exclusive access to the
    # bzr repository.
    #
    @contextmanager
    def _locked(self):
        lockdir = os.path.join(self.get_mirror_directory(), 'locks')
        lockfile = os.path.join(
            lockdir,
            utils.url_directory_name(self.original_url) + '.lock'
        )
        os.makedirs(lockdir, exist_ok=True)
        with open(lockfile, 'w') as lock:
            fcntl.flock(lock, fcntl.LOCK_EX)
            try:
                yield
            finally:
                fcntl.flock(lock, fcntl.LOCK_UN)

    def _check_ref(self):
        # If the mirror doesnt exist yet, then we dont have the ref
        if not os.path.exists(self._get_branch_dir()):
            return False

        return self.call([self.host_bzr, "revno",
                          "--revision=revno:{}".format(self.ref),
                          self._get_branch_dir()]) == 0

    def _get_branch_dir(self):
        return os.path.join(self._get_mirror_dir(), self.tracking)

    def _get_mirror_dir(self):
        return os.path.join(self.get_mirror_directory(),
                            utils.url_directory_name(self.original_url))

    def _ensure_mirror(self, skip_ref_check=False):
        mirror_dir = self._get_mirror_dir()
        bzr_metadata_dir = os.path.join(mirror_dir, ".bzr")
        if not os.path.exists(bzr_metadata_dir):
            self.call([self.host_bzr, "init-repo", "--no-trees", mirror_dir],
                      fail="Failed to initialize bzr repository")

        branch_dir = os.path.join(mirror_dir, self.tracking)
        branch_url = self.url + "/" + self.tracking
        if not os.path.exists(branch_dir):
            # `bzr branch` the branch if it doesn't exist
            # to get the upstream code
            self.call([self.host_bzr, "branch", branch_url, branch_dir],
                      fail="Failed to branch from {} to {}".format(branch_url, branch_dir))

        else:
            # `bzr pull` the branch if it does exist
            # to get any changes to the upstream code
            self.call([self.host_bzr, "pull", "--directory={}".format(branch_dir), branch_url],
                      fail="Failed to pull new changes for {}".format(branch_dir))

        if not skip_ref_check and not self._check_ref():
            raise SourceError("Failed to ensure ref '{}' was mirrored".format(self.ref),
                              reason="ref-not-mirrored")


def setup():
    return BzrSource
