# Copyright 2015 Google Inc. 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.

RUST_FILETYPE = FileType([".rs"])
A_FILETYPE = FileType([".a"])

def _relative(src_path, dest_path):
  """
  Returns the relative path from src_path to dest_path
  """
  src_parts = src_path.split("/")
  dest_parts = dest_path.split("/")
  n = 0
  done = False
  for src_part, dest_part in zip(src_parts, dest_parts):
    if src_part != dest_part:
      break
    n += 1

  relative_path = ""
  for i in range(n, len(src_parts)):
    relative_path += "../"
  relative_path += "/".join(dest_parts[n:])

  return relative_path

def _create_setup_cmd(lib, deps_dir):
  """
  Helper function to construct a command for symlinking a library into the
  deps directory.
  """
  return (
      "ln -sf " + _relative(deps_dir, lib.path) + " " +
      deps_dir + "/" + lib.basename + "\n"
  )

# TODO(dzc): rust_binary should not be able to depend on cc_library
def _setup_deps(deps, name, working_dir):
  """
  Walks through dependencies and constructs the necessary commands for linking
  to all the necessary dependencies.
  """
  deps_dir = working_dir + "/" + name + ".deps"
  setup_cmd = ["rm -rf " + deps_dir + "; mkdir " + deps_dir + "\n"]

  has_rlib = False
  has_native = False

  libs = set()
  transitive_libs = set()
  symlinked_libs = set()
  link_flags = []
  for dep in deps:
    if hasattr(dep, "rust_lib"):
      libs += [dep.rust_lib]
      transitive_libs += [dep.rust_lib]
      symlinked_libs += [dep.rust_lib]
      link_flags += [(
          "--extern " + dep.label.name + "=" +
          deps_dir + "/" + dep.rust_lib.basename
      )]
      has_rlib = True

    if hasattr(dep, "transitive_libs"):
      transitive_libs += dep.transitive_libs
      symlinked_libs += dep.transitive_libs

    # If this rule depends on a cc_library
    if hasattr(dep, "cc"):
      native_libs = A_FILETYPE.filter(dep.cc.libs)
      libs += native_libs
      transitive_libs += native_libs
      symlinked_libs += native_libs
      link_flags += ["-l static=" + dep.label.name]
      has_native = True

  for symlinked_lib in symlinked_libs:
    setup_cmd += [_create_setup_cmd(symlinked_lib, deps_dir)]

  search_flags = []
  if has_rlib:
    search_flags += ["-L dependency=" + deps_dir]
  if has_native:
    search_flags += ["-L native=" + deps_dir]

  return struct(
      libs = list(libs),
      transitive_libs = list(transitive_libs),
      setup_cmd = setup_cmd,
      search_flags = search_flags,
      link_flags = link_flags,
  )

def _get_features_flags(features):
  """
  Constructs a string containing the feature flags from the features specified
  in the features attribute.
  """
  features_flags = []
  for feature in features:
    features_flags += [" --cfg feature=\\\"" + feature + "\\\""]
  return features_flags

def _build_rustc_command(ctx, crate_type, src, output_dir, depinfo,
                         extra_flags=[]):
  """
  Builds the rustc command
  """

  # Paths to the Rust compiler and standard libraries.
  rustc_path = ctx.file._rustc.path
  rustlib_path = ctx.files._rustlib[0].dirname

  # Paths to cc (for linker) and ar
  cpp_fragment = ctx.fragments.cpp
  cc = cpp_fragment.compiler_executable
  ar = cpp_fragment.ar_executable
  # Currently, the CROSSTOOL config for darwin sets ar to "libtool". Because
  # rust uses ar-specific flags, use /usr/bin/ar in this case.
  # TODO(dzc): This is not ideal. Remove this workaround once ar_executable
  # always points to an ar binary.
  ar_str = "%s" % ar
  if ar_str.find("libtool", 0) != -1:
    ar = "/usr/bin/ar"

  # Construct features flags
  features_flags = _get_features_flags(ctx.attr.crate_features)

  return " ".join([
      "set -e;",
      " ".join(depinfo.setup_cmd),
      rustc_path + " " + src,
      "--crate-name " + ctx.label.name,
      "--crate-type " + crate_type,
      "-g",
      "--codegen ar=%s" % ar,
      "--codegen linker=%s" % cc,
      "-L all=" + rustlib_path,
      " ".join(extra_flags),
      " ".join(features_flags),
      "--out-dir " + output_dir,
      "--emit=dep-info,link",
      " ".join(depinfo.search_flags),
      " ".join(depinfo.link_flags),
      " ".join(ctx.attr.rustc_flags),
  ])

def _rust_library_impl(ctx):
  """
  Implementation for rust_library Skylark rule.
  """

  # Find lib.rs
  srcs = ctx.files.srcs
  lib_rs = None
  crate_name_rs = ctx.label.name + ".rs"
  for src in srcs:
    if src.basename == "lib.rs" or src.basename == crate_name_rs:
      lib_rs = src.path

  if not lib_rs:
    fail("No lib.rs or source file matching crate name found.")

  # Output library
  rust_lib = ctx.outputs.rust_lib
  output_dir = rust_lib.dirname

  # Dependencies
  depinfo = _setup_deps(ctx.attr.deps, ctx.label.name, output_dir)

  # Build rustc command
  cmd = _build_rustc_command(
      ctx = ctx,
      crate_type = "lib",
      src = lib_rs,
      output_dir = output_dir,
      depinfo = depinfo)

  # Compile action.
  ctx.action(
      inputs = srcs + ctx.files.data + depinfo.libs,
      outputs = [rust_lib],
      mnemonic = 'Rustc',
      command = cmd,
      use_default_shell_env = True,
      progress_message = "Compiling Rust library " + ctx.label.name
  )

  return struct(
      files = set([rust_lib]),
      transitive_libs = depinfo.transitive_libs,
      rust_lib = rust_lib,
  )

def _rust_binary_impl_common(ctx, extra_flags = []):
  """
  Implementation for rust_binary Skylark rule.
  """

  # Find main.rs.
  srcs = ctx.files.srcs
  main_rs = None
  crate_name_rs = ctx.label.name + ".rs"
  for src in srcs:
    if src.basename == "main.rs" or src.basename == crate_name_rs:
      main_rs = src.path

  if not main_rs:
    fail("No main.rs or source file matching crate name found.")

  # Output binary
  rust_binary = ctx.outputs.executable
  output_dir = rust_binary.dirname

  # Dependencies
  depinfo = _setup_deps(ctx.attr.deps, ctx.label.name, output_dir)

  # Build rustc command.
  cmd = _build_rustc_command(
      ctx = ctx,
      crate_type = "bin",
      src = main_rs,
      output_dir = output_dir,
      depinfo = depinfo,
      extra_flags = extra_flags)

  # Compile action.
  ctx.action(
      inputs = srcs + ctx.files.data + depinfo.libs,
      outputs = [rust_binary],
      mnemonic = 'Rustc',
      command = cmd,
      use_default_shell_env = True,
      progress_message = "Compiling Rust binary " + ctx.label.name
  )

def _rust_binary_impl(ctx):
  """
  Implementation for rust_binary Skylark rule.
  """
  return _rust_binary_impl_common(ctx)

def _rust_test_impl(ctx):
  """
  Implementation for rust_test Skylark rule.
  """
  return _rust_binary_impl_common(ctx, ["--test"])

_rust_common_attrs = {
    "srcs": attr.label_list(allow_files = RUST_FILETYPE),
    "data": attr.label_list(allow_files = True, cfg = DATA_CFG),
    "deps": attr.label_list(),
    "crate_features": attr.string_list(),
    "rustc_flags": attr.string_list(),
    "_rustc": attr.label(
        default = Label("//tools/build_rules/rust:rustc"),
        executable = True,
        single_file = True),
    "_rustlib": attr.label(default = Label("//tools/build_rules/rust:rustlib")),
}

rust_library = rule(
    _rust_library_impl,
    attrs = _rust_common_attrs,
    outputs = {
        "rust_lib": "lib%{name}.rlib",
    },
    fragments = ["cpp"],
)

rust_binary = rule(
    _rust_binary_impl,
    executable = True,
    attrs = _rust_common_attrs,
    fragments = ["cpp"],
)

rust_test = rule(
    _rust_test_impl,
    executable = True,
    attrs = _rust_common_attrs,
    test = True,
    fragments = ["cpp"],
)

