# Copyright 2014 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.

pex_file_types = FileType([".py"])
egg_file_types = FileType([".egg", ".whl"])
pex_test_file_types = FileType(["_unittest.py", "_test.py"])

def collect_transitive_sources(ctx):
  source_files = set(order="compile")
  for dep in ctx.attr.deps:
    source_files += dep.transitive_py_files

  source_files += pex_file_types.filter(ctx.files.srcs)
  return source_files

def collect_transitive_eggs(ctx):
  transitive_eggs = set(order="compile")
  for dep in ctx.attr.deps:
    transitive_eggs += dep.transitive_egg_files
  transitive_eggs += egg_file_types.filter(ctx.files.eggs)
  return transitive_eggs

def collect_transitive_reqs(ctx):
  transitive_reqs = set(order="compile")
  for dep in ctx.attr.deps:
    transitive_reqs += dep.transitive_reqs
  transitive_reqs += ctx.attr.reqs

  return transitive_reqs

def pex_library_impl(ctx):
  transitive_sources = collect_transitive_sources(ctx)
  transitive_eggs = collect_transitive_eggs(ctx)
  transitive_reqs = collect_transitive_reqs(ctx)
  return struct(
      files = set(),
      transitive_py_files = transitive_sources,
      transitive_reqs = transitive_reqs,
      transitive_egg_files = transitive_eggs)

def get_package_from_path(pkg_path):
  return pkg_path.replace('/', '.')[:-3]

# Converts map to text format. Each file on separate line.
def textify_pex_input(input_map):
  kv_pairs = ['\t%s:%s' % (pkg, input_map[pkg]) for pkg in input_map.keys()]
  return '\n'.join(kv_pairs)

def write_pex_manifest_text(modules, prebuilt_libs, resources, requirements):
  return ('modules:\n%s\nrequirements:\n%s\nresources:\n%s\nnativeLibraries:\nprebuiltLibraries:\n%s' % (
      textify_pex_input(modules),
      textify_pex_input(dict(zip(requirements,requirements))),
      textify_pex_input(resources),
      textify_pex_input(prebuilt_libs)))

def get_module_path(ctx, pkg_path):
  genfiles_dir = ctx.configuration.genfiles_dir.path
  if pkg_path.startswith(genfiles_dir):
    module_path = pkg_path[len(genfiles_dir):]
    if module_path.startswith('/'):
      return module_path[1:]
    return module_path 
  return pkg_path

def make_manifest(ctx, output):
  transitive_sources = collect_transitive_sources(ctx)
  transitive_reqs = collect_transitive_reqs(ctx)
  transitive_eggs = collect_transitive_eggs(ctx)
  transitive_resources = ctx.files.resources
  pex_modules = {}
  pex_prebuilt_libs = {}
  pex_resources = {}
  pex_requirements = []
  for f in transitive_sources:
    pex_modules[get_module_path(ctx, f.path)] = f.path

  for f in transitive_eggs:
    pex_prebuilt_libs[get_module_path(ctx, f.path)] = f.path

  for f in transitive_resources:
    pex_resources[get_module_path(ctx, f.path)] = f.path

  manifest_text = write_pex_manifest_text(pex_modules, pex_prebuilt_libs, pex_resources, transitive_reqs)
  ctx.action(
    inputs = list(transitive_sources) + list(transitive_eggs) + list(transitive_resources),
    outputs = [ output ],
    command = ('touch %s && echo "%s" > %s' % (output.path, manifest_text, output.path)))

def common_pex_arguments(entry_point, deploy_pex_path, manifest_file_path):
  arguments = ['--entry-point', entry_point]

  # Our internal build environment requires extra args injected and this is a brutal hack. Ideally
  # bazel would provide a mechanism to swap in env-specific global params here
  #EXTRA_PEX_ARGS#
  arguments += [deploy_pex_path]
  arguments += [manifest_file_path]
  return arguments

def pex_binary_impl(ctx):
  if not ctx.file.main:
    main_file = pex_file_types.filter(ctx.files.srcs)[0]
  else:
    main_file = ctx.file.main

  # Package name is same as folder name followed by filename (without .py extension)
  main_pkg = get_package_from_path(main_file.path)

  deploy_pex = ctx.new_file(
      ctx.configuration.bin_dir, ctx.outputs.executable, '.pex')

  manifest_file = ctx.new_file(
      ctx.configuration.bin_dir, deploy_pex, '.manifest')
  make_manifest(ctx, manifest_file)

  transitive_sources = collect_transitive_sources(ctx)
  transitive_eggs = collect_transitive_eggs(ctx)
  transitive_resources = ctx.files.resources
  pexbuilder = ctx.executable._pexbuilder

  # form the arguments to pex builder
  arguments =  [] if ctx.attr.zip_safe else ["--not-zip-safe"]
  arguments += common_pex_arguments(main_pkg, deploy_pex.path, manifest_file.path)

  # form the inputs to pex builder
  inputs =  [main_file, manifest_file]
  inputs += list(transitive_sources)
  inputs += list(transitive_eggs)
  inputs += list(transitive_resources)

  ctx.action(
      mnemonic = "PexPython",
      inputs = inputs,
      outputs = [deploy_pex],
      executable = pexbuilder,
      arguments = arguments)

  executable = ctx.outputs.executable
  ctx.action(
      inputs = [deploy_pex],
      outputs = [executable],
      command = "cp %s %s" % (deploy_pex.path, executable.path))

  return struct(files = set([executable]))

def pex_test_impl(ctx):
  deploy_pex = ctx.new_file(
      ctx.configuration.bin_dir, ctx.outputs.executable, '.pex')

  manifest_file = ctx.new_file(
      ctx.configuration.bin_dir, deploy_pex, '.manifest')
  make_manifest(ctx, manifest_file)

  # Get pex test files
  transitive_sources = collect_transitive_sources(ctx)
  transitive_eggs = collect_transitive_eggs(ctx)
  transitive_resources = ctx.files.resources
  pexbuilder = ctx.executable._pexbuilder
  pex_test_files = pex_test_file_types.filter(pex_file_types.filter(transitive_sources))
  test_run_args = ' '.join([f.path for f in pex_test_files])

  ctx.action(
      inputs = [manifest_file] + list(transitive_sources) + list(transitive_eggs) + list(transitive_resources),
      executable = pexbuilder,
      outputs = [ deploy_pex ],
      mnemonic = "PexPython",
      arguments = common_pex_arguments('pytest', deploy_pex.path, manifest_file.path))

  executable = ctx.outputs.executable
  ctx.action(
      inputs = [ deploy_pex ],
      outputs = [ executable ],
      command = "echo PYTHONDONTWRITEBYTECODE=1 \"`pwd`/%s `pwd`/%s\" > %s" % (deploy_pex.path, test_run_args, executable.path))

  return struct(files = set([executable]))


pex_srcs_attr = attr.label_list(
    flags=["DIRECT_COMPILE_TIME_INPUT"],
    allow_files = pex_file_types
)

pex_deps_attr = attr.label_list(
    providers = ["transitive_py_files", "transitive_egg_files", "transitive_reqs"],
    allow_files = False)

eggs_attr = attr.label_list(
    flags=["DIRECT_COMPILE_TIME_INPUT"],
    allow_files = egg_file_types)

resource_attr = attr.label_list(
    allow_files = True)

pex_attrs = {
    "srcs": pex_srcs_attr,
    "deps": pex_deps_attr,
    "eggs": eggs_attr,
    "reqs": attr.string_list(),
    "resources": resource_attr,
    "main": attr.label(allow_files=True, single_file=True)
}

pex_bin_attrs = pex_attrs + {
    "zip_safe": attr.bool(
        default = True,
        mandatory = False
    )
}

pex_library = rule(
    pex_library_impl,
    attrs = pex_attrs
)

pex_binary_outputs = {
    "deploy_pex": "%{name}.pex"
}

pex_binary = rule(
    pex_binary_impl,
    executable = True,
    attrs = pex_bin_attrs + {
        "_pexbuilder": attr.label(
            default = Label("//3rdparty/pex:_pex"),
            allow_files = False,
            executable = True,
        ),
    },
)

pex_test = rule(
    pex_test_impl,
    executable = True,
    attrs = pex_attrs + {
        "_pexbuilder": attr.label(
            default = Label("//3rdparty/pex:_pex"),
            allow_files = False,
            executable = True,
        ),
    },
    test = True,
)
