# Copyright 2015 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Rules for cloning external git repositories."""

def _clone_or_update(ctx):
  if ((ctx.attr.tag == "" and ctx.attr.commit == "") or
      (ctx.attr.tag != "" and ctx.attr.commit != "")):
    ctx.fail("Exactly one of commit and tag must be provided")
  if ctx.attr.commit != "":
    ref = ctx.attr.commit
  else:
    ref = "tags/" + ctx.attr.tag

  st = ctx.execute(["bash", '-c', """
set -ex
( cd {working_dir} &&
    if ! ( cd '{dir}' && git rev-parse --git-dir ) >/dev/null 2>&1; then
      rm -rf '{dir}'
      git clone '{remote}' '{dir}'
    fi
    cd '{dir}'
    git reset --hard {ref} || (git fetch && git reset --hard {ref})
    git clean -xdf )
  """.format(
    working_dir=ctx.path(".").dirname,
    dir=ctx.path("."),
    remote=ctx.attr.remote,
    ref=ref,
  )])
  if st.return_code != 0:
    fail("error cloning %s:\n%s" % (ctx.name, st.stderr))
  if ctx.attr.init_submodules:
    st = ctx.execute(["bash", '-c', """
set -ex
(   cd '{dir}'
    git submodule update --init --checkout --force )
  """.format(
    dir=ctx.path("."),
    )])
    if st.return_code != 0:
      fail("error updating submodules %s:\n%s" % (ctx.name, st.stderr))


def _new_git_repository_implementation(ctx):
  if ((ctx.attr.build_file == None and ctx.attr.build_file_content == '') or
      (ctx.attr.build_file != None and ctx.attr.build_file_content != '')):
    ctx.fail("Exactly one of build_file and build_file_content must be provided.")
  _clone_or_update(ctx)
  ctx.file('WORKSPACE', "workspace(name = \"{name}\")\n".format(name=ctx.name))
  if ctx.attr.build_file:
    ctx.symlink(ctx.attr.build_file, 'BUILD')
  else:
    ctx.file('BUILD', ctx.attr.build_file_content)

def _git_repository_implementation(ctx):
  _clone_or_update(ctx)


_common_attrs = {
  "remote": attr.string(mandatory=True),
  "commit": attr.string(default=""),
  "tag": attr.string(default=""),
  "init_submodules": attr.bool(default=False),
}


new_git_repository = repository_rule(
  implementation=_new_git_repository_implementation,
  attrs=_common_attrs + {
    "build_file": attr.label(),
    "build_file_content": attr.string(),
  }
)
"""Clone an external git repository.

Clones a Git repository, checks out the specified tag, or commit, and
makes its targets available for binding.

Args:
  name: A unique name for this rule.

  build_file: The file to use as the BUILD file for this repository.
    Either build_file or build_file_content must be specified.

    This attribute is a label relative to the main workspace. The file
    does not need to be named BUILD, but can be (something like
    BUILD.new-repo-name may work well for distinguishing it from the
    repository's actual BUILD files.

  build_file_content: The content for the BUILD file for this repository.
    Either build_file or build_file_content must be specified.

  init_submodules: Whether to clone submodules in the repository.

  remote: The URI of the remote Git repository.
"""

git_repository = repository_rule(
  implementation=_git_repository_implementation,
  attrs=_common_attrs,
)
"""Clone an external git repository.

Clones a Git repository, checks out the specified tag, or commit, and
makes its targets available for binding.

Args:
  name: A unique name for this rule.

  init_submodules: Whether to clone submodules in the repository.

  remote: The URI of the remote Git repository.
"""
